From 52a11cbfcf0cfb32628b6953588b6af4037ac0b6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 28 Mar 2001 03:04:51 -0800 Subject: [PATCH] IA-64 ABI Exception Handling. From-SVN: r40924 --- gcc/ChangeLog | 114 + gcc/Makefile.in | 33 +- gcc/basic-block.h | 10 +- gcc/bb-reorder.c | 14 - gcc/builtins.c | 7 +- gcc/builtins.def | 1 + gcc/c-common.c | 5 + gcc/c-decl.c | 9 +- gcc/calls.c | 25 +- gcc/cp/ChangeLog | 56 + gcc/cp/cp-tree.def | 5 + gcc/cp/cp-tree.h | 23 +- gcc/cp/decl.c | 13 +- gcc/cp/decl2.c | 4 - gcc/cp/dump.c | 13 + gcc/cp/error.c | 2 +- gcc/cp/except.c | 970 ++-- gcc/cp/expr.c | 14 +- gcc/cp/semantics.c | 39 +- gcc/cp/tree.c | 1 + gcc/crtstuff.c | 6 +- gcc/dwarf2.h | 30 +- gcc/dwarf2out.c | 108 +- gcc/dwarf2out.h | 2 + gcc/eh-common.h | 162 - gcc/except.c | 5709 ++++++++++--------- gcc/except.h | 553 +- gcc/expr.c | 19 +- gcc/expr.h | 21 +- gcc/final.c | 26 +- gcc/flow.c | 417 +- gcc/frame-dwarf2.c | 778 --- gcc/frame.h | 287 - gcc/function.c | 59 +- gcc/function.h | 4 + gcc/ifcvt.c | 11 +- gcc/integrate.c | 92 +- gcc/java/ChangeLog | 31 + gcc/java/Make-lang.in | 2 +- gcc/java/check-init.c | 1 + gcc/java/decl.c | 24 +- gcc/java/except.c | 66 +- gcc/java/expr.c | 12 +- gcc/java/java-tree.h | 4 +- gcc/java/jcf-write.c | 8 +- gcc/java/parse.h | 8 - gcc/java/parse.y | 15 +- gcc/jump.c | 18 - gcc/libgcc-std.ver | 35 +- gcc/libgcc2.c | 1218 ---- gcc/md.texi | 32 +- gcc/mklibgcc.in | 36 +- gcc/optabs.c | 13 +- gcc/rtl.def | 5 + gcc/rtl.h | 4 - gcc/stmt.c | 122 +- gcc/tm.texi | 48 + gcc/toplev.c | 49 +- gcc/tree.def | 15 +- gcc/{frame.c => unwind-dw2-fde.c} | 335 +- gcc/unwind-dw2-fde.h | 120 + gcc/unwind-dw2.c | 1217 ++++ gcc/unwind-sjlj.c | 259 + gcc/unwind.h | 166 + gcc/unwind.inc | 232 + libjava/ChangeLog | 26 + libjava/Makefile.am | 11 +- libjava/Makefile.in | 8 +- libjava/configure | 776 +-- libjava/configure.host | 6 - libjava/configure.in | 70 +- libjava/exception.cc | 620 +- libjava/gcj/javaprims.h | 1 - libjava/libgcj.spec.in | 2 +- libstdc++-v3/ChangeLog | 20 + libstdc++-v3/Makefile.in | 45 +- libstdc++-v3/acinclude.m4 | 60 + libstdc++-v3/aclocal.m4 | 60 + libstdc++-v3/config.h.in | 3 + libstdc++-v3/configure | 1674 +++--- libstdc++-v3/configure.in | 1 + libstdc++-v3/libio/Makefile.in | 19 +- libstdc++-v3/libmath/Makefile.in | 20 +- libstdc++-v3/libsupc++/Makefile.am | 9 +- libstdc++-v3/libsupc++/Makefile.in | 57 +- libstdc++-v3/libsupc++/eh_alloc.cc | 157 + libstdc++-v3/libsupc++/eh_aux_runtime.cc | 56 + libstdc++-v3/libsupc++/eh_catch.cc | 103 + libstdc++-v3/libsupc++/eh_exception.cc | 44 + libstdc++-v3/libsupc++/eh_globals.cc | 120 + libstdc++-v3/libsupc++/eh_personality.cc | 599 ++ libstdc++-v3/libsupc++/eh_terminate.cc | 87 + libstdc++-v3/libsupc++/eh_throw.cc | 102 + libstdc++-v3/libsupc++/exception_support.cc | 388 -- libstdc++-v3/libsupc++/exception_support.h | 65 - libstdc++-v3/libsupc++/pure.cc | 11 +- libstdc++-v3/libsupc++/tinfo2.cc | 28 - libstdc++-v3/libsupc++/unwind-cxx.h | 163 + libstdc++-v3/libsupc++/vec.cc | 18 +- libstdc++-v3/src/Makefile.in | 154 +- 100 files changed, 9951 insertions(+), 9369 deletions(-) delete mode 100644 gcc/eh-common.h delete mode 100644 gcc/frame-dwarf2.c delete mode 100644 gcc/frame.h rename gcc/{frame.c => unwind-dw2-fde.c} (66%) create mode 100644 gcc/unwind-dw2-fde.h create mode 100644 gcc/unwind-dw2.c create mode 100644 gcc/unwind-sjlj.c create mode 100644 gcc/unwind.h create mode 100644 gcc/unwind.inc create mode 100644 libstdc++-v3/libsupc++/eh_alloc.cc create mode 100644 libstdc++-v3/libsupc++/eh_aux_runtime.cc create mode 100644 libstdc++-v3/libsupc++/eh_catch.cc create mode 100644 libstdc++-v3/libsupc++/eh_exception.cc create mode 100644 libstdc++-v3/libsupc++/eh_globals.cc create mode 100644 libstdc++-v3/libsupc++/eh_personality.cc create mode 100644 libstdc++-v3/libsupc++/eh_terminate.cc create mode 100644 libstdc++-v3/libsupc++/eh_throw.cc delete mode 100644 libstdc++-v3/libsupc++/exception_support.cc delete mode 100644 libstdc++-v3/libsupc++/exception_support.h create mode 100644 libstdc++-v3/libsupc++/unwind-cxx.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8994dd2a9cc..deb12a56c02 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,117 @@ +2001-03-28 Richard Henderson + + * except.c: Rewrite entirely for IA-64 ABI exception handling. + * except.h: Likewise. + + * Makefile.in (LIB2ADDEH): Mention unwind-dw2*.c + (LIB2ADDEHDEP): New. + (LIB2FUNCS_EH): Remove. + (LIB2ADD): Remove LIB2ADDEH. + (libgcc.mk): Pass LIB2ADDEHDEP, don't pass LIB2FUNCS_EH. + (LIBGCC_DEPS): Use LIB2ADDEHDEP. + (crt{begin,end}[S].o): Likewise. + (except.o): Update includes. + * mklibgcc.in: Remove LIB2FUNCS_EH, add LIB2ADDEH, LIB2ADDEHDEP. + (libgcc2_c_dep): Use LIB2ADDEHDEP. + + * basic-block.h (struct basic_block_def): Remove eh_beg, eh_end. + * bb-reorder.c (reorder_basic_blocks): Don't disable for EH. + * builtins.def (BUILT_IN_EH_RETURN_DATA_REGNO): New. + * builtins.c (expand_builtin): Implement it. + [BUILT_IN_EH_RETURN]: Update for nr arguments change. + * c-common.c (c_common_nodes_and_builtins): Declare it. + * c-decl.c (init_decl_processing): Update __builtin_eh_return. + * calls.c (libfunc_nothrow): Remove. + (emit_library_call_value_1): Don't call it. + * crtstuff.c: Include unwind-dw2-fde.h instead of frame.h. + * dwarf2.h (dwarf_call_frame_info): Add dwarf2.1 elements. + (DW_EH_PE_*): New defines for pointer encoding in .eh_frame. + * dwarf2out.c (struct dw_fde_struct): Add uses_eh_lsda, funcdef_number. + (current_funcdef_number): Globalize. + (output_call_frame_info): Emit frame data if an lsda is needed. + Generate augmentation for personality routine. Don't play with + difference symbols. + (dwarf2out_begin_prologue): Record funcdef_number. + * dwarf2out.h (current_funcdef_number): Declare. + * expr.c (expand_expr): Update for except.h name changes. + Remove POPDCC_EXPR, POPDHC_EXPR. Add EXC_PTR_EXPR. + * expr.h (LTI_throw, LTI_rethrow): Remove. + (LTI_sjthrow, LTI_sjpopnthrow, LTI_terminate): Remove. + (LTI_eh_rtime_match): Remove. + (LTI_unwind_resume, LTI_eh_personality): Add. + (LTI_unwind_sjlj_register, LTI_unwind_sjlj_unregister): Add. + * final.c (final): Don't call check_exception_handler_labels, + init_insn_eh_region, or free_insn_eh_region. + (final_scan_insn): Always emit debug labels for + NOTE_INSN_EH_REGION notes. + * flags.h (flag_new_exceptions): Remove. + * flow.c (entry_exit_blocks): Remove eh_beg, eh_end. + (record_active_eh_regions): Remove. + (count_basic_blocks): Check all instructions for REG_EH_REGION. + Use can_throw_internal. + (find_basic_blocks_1): Likewise. + (move_stray_eh_region_notes): Remove. + (find_label_refs): No eh_return_stub_label. + (make_edges): Likewise. No init/free_eh_nesting_info. Handle RESX. + (make_eh_edge): No eh_nest_info. Update for reachable_handlers + changes. + (delete_unreachable_blocks): Don't track deleted handlers. + (flow_delete_block): Use maybe_remove_eh_handler. + (delete_eh_regions): Remove. + (merge_blocks): Don't check for eh region match. + (mark_regs_live_at_end): Handle EH_RETURN_DATA_REGNO, + EH_RETURN_STACKADJ_RTX, EH_RETURN_HANDLER_RTX. + (init_propagate_block_info): Disable dead frame store optimization + when current_function_calls_eh_return. + (dump_bb): Don't print eh_beg, eh_end. + * function.c (fixup_var_refs): No catch_clauses. + (expand_function_end): Likewise. Call expand_eh_return before + the return register use. Call sjlj_emit_function_exit_after. + (expand_function_start): Force pseudo DECL_RESULT if sjlj exceptions. + * function.h (struct function): Add calls_eh_return, uses_eh_lsda. + * ifcvt.c (dead_or_predicable): Remove eh region check. + * integrate.c (function_cannot_inline_p): Disallow __builtin_eh_return. + Don't check for EH vs parameters. + (expand_inline_function_eh_labelmap, eif_eh_map): Remove. + (expand_inline_function): Call duplicate_eh_regions. + (copy_insn_list): Don't handle NOTE_INSN_EH_REGION_BEG/END. + (copy_insn_notes): Remap REG_EH_REGION notes. + (copy_rtx_and_substitute): Remove SYMBOL_REF_NEED_ADJUST check. + * integrate.h (struct inline_remap): Add local_return_label. + * jump.c (jump_optimize_1): Don't init/free_insn_eh_region, nor + check_exception_handler_labels, nor exception_optimize. + (find_cross_jump): No EH region check. + * optabs.c (init_optabs): Update for changed eh libfuncs. + * rtl.def (RESX): New. + * rtl.h (SYMBOL_REF_NEED_ADJUST): Remove. + * stmt.c (expand_decl_cleanup): Simplify using_eh_for_cleanups_p + checks. Update for except.h name changes. + (expand_cleanups): Likewise. + (expand_dcc_cleanup, expand_dhc_cleanup): Remove. + * toplev.c (dump_file_index, dump_file): Add .02.eh dump. + (compile_file): Call init_eh before init_optabs. Don't + output_exception_table here. + (rest_of_compilation): Call convert_from_eh_region_ranges, + convert_to_eh_region_ranges, output_function_exception_table. + Don't emit_eh_context. + * tree.def (POPDHC_EXPR, POPDCC_EXPR): Remove. + (EXC_PTR_EXPR): New. + + * md.texi (eh_epilogue): Remove. + (eh_return): Document. + * tm.texi (EH_RETURN_DATA_REGNO): Document. + (EH_RETURN_STACKADJ_RTX, EH_RETURN_HANDLER_RTX): Document. + + * eh-common.h: Remove file. + * frame-dwarf2.c, frame.c, frame.h: Remove files. + * libgcc2.c (L_eh): Remove. + + * unwind-dw2-fde.c: New file, largely copied from frame.c. + * unwind-dw2-fde.h: New file. + * unwind-dw2.c: New file, largely cribbed from frame-dwarf2.c. + * unwind-sjlj.c, unwind.h, unwind.inc: New files. + * libgcc-std.ver: Update for eh symbols. + 2001-03-27 Richard Henderson * regmove.c (perhaps_ends_bb_p): Use can_throw_internal to diff --git a/gcc/Makefile.in b/gcc/Makefile.in index eaac7398a1b..5888dcb927c 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -397,8 +397,10 @@ LIBGCC2_INCLUDES = # Additional target-dependent options for compiling libgcc2.a. TARGET_LIBGCC2_CFLAGS = -# Additional sources to handle exceptions; overridden by some targets. -LIB2ADDEH = $(srcdir)/frame-dwarf2.c +# Additional sources to handle exceptions; overridden on ia64. +LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ + $(srcdir)/unwind-sjlj.c +LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h # libgcc1-test target (must also be overridable for a target) LIBGCC1_TEST = libgcc1-test @@ -794,8 +796,6 @@ LIB2FUNCS = _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \ _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 \ _ctors -LIB2FUNCS_EH = _eh - FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \ @@ -1033,7 +1033,7 @@ xlimits.h: glimits.h limitx.h limity.h # # Build libgcc.a. -LIB2ADD = $(LIB2ADDEH) $(LIB2FUNCS_EXTRA) +LIB2ADD = $(LIB2FUNCS_EXTRA) libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) xgcc$(exeext) objext='$(objext)' \ @@ -1043,8 +1043,9 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) xgcc$(exeext) LIB1ASMFUNCS='$(LIB1ASMFUNCS)' \ LIB1FUNCS_EXTRA='$(LIB1FUNCS_EXTRA)' \ LIB2FUNCS='$(LIB2FUNCS)' \ - LIB2FUNCS_EH='$(LIB2FUNCS_EH)' \ LIB2ADD='$(LIB2ADD)' \ + LIB2ADDEH='$(LIB2ADDEH)' \ + LIB2ADDEHDEP='$(LIB2ADDEHDEP)' \ FPBIT='$(FPBIT)' \ FPBIT_FUNCS='$(FPBIT_FUNCS)' \ DPBIT='$(DPBIT)' \ @@ -1064,8 +1065,9 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) xgcc$(exeext) # All the things that might cause us to want to recompile bits of libgcc. LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \ libgcc.mk $(srcdir)/libgcc1.c $(srcdir)/libgcc2.c $(TCONFIG_H) \ - $(MACHMODE_H) longlong.h frame.h gbl-ctors.h config.status \ - stmp-int-hdrs tsystem.h $(FPBIT) $(DPBIT) $(LIB2ADD) $(EXTRA_PARTS) + $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \ + tsystem.h $(FPBIT) $(DPBIT) $(LIB2ADD) $(LIB2ADDEH) $(LIB2ADDEHDEP) \ + $(EXTRA_PARTS) libgcc.a: $(LIBGCC_DEPS) $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ @@ -1125,14 +1127,14 @@ stmp-multilib: $(LIBGCC_DEPS) # linked using GCC on systems using COFF or ELF, for the sake of C++ # constructors. $(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ - frame.h gbl-ctors.h stmp-int-hdrs tsystem.h + gbl-ctors.h stmp-int-hdrs tsystem.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -finhibit-size-directive -fno-inline-functions \ -fno-exceptions $(CRTSTUFF_T_CFLAGS) @inhibit_libc@ \ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -o $(T)crtbegin$(objext) $(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ - frame.h gbl-ctors.h stmp-int-hdrs tsystem.h + gbl-ctors.h stmp-int-hdrs tsystem.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -finhibit-size-directive -fno-inline-functions \ -fno-exceptions $(CRTSTUFF_T_CFLAGS) @inhibit_libc@ \ @@ -1140,7 +1142,7 @@ $(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ # These are versions of crtbegin and crtend for shared libraries. $(T)crtbeginS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ - frame.h gbl-ctors.h stmp-int-hdrs tsystem.h + gbl-ctors.h stmp-int-hdrs tsystem.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -finhibit-size-directive -fno-inline-functions \ -fno-exceptions $(CRTSTUFF_T_CFLAGS_S) @inhibit_libc@ \ @@ -1148,7 +1150,7 @@ $(T)crtbeginS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ -o $(T)crtbeginS$(objext) $(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ - frame.h gbl-ctors.h stmp-int-hdrs tsystem.h + gbl-ctors.h stmp-int-hdrs tsystem.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -finhibit-size-directive -fno-inline-functions \ -fno-exceptions $(CRTSTUFF_T_CFLAGS_S) @inhibit_libc@ \ @@ -1394,8 +1396,9 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \ insn-config.h hard-reg-set.h $(EXPR_H) except.h \ $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ - function.h $(EXPR_H) $(REGS_H) hard-reg-set.h \ - insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h $(GGC_H) $(TM_P_H) + except.h function.h $(EXPR_H) integrate.h \ + insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ + dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H) expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \ $(REGS_H) $(EXPR_H) insn-config.h $(RECOG_H) \ output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h \ @@ -1414,7 +1417,7 @@ explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ toplev.h function.h $(TM_P_H) optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ insn-config.h $(EXPR_H) $(RECOG_H) reload.h \ - toplev.h $(GGC_H) real.h $(TM_P_H) + toplev.h $(GGC_H) real.h $(TM_P_H) except.h dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h $(REGS_H) \ insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h \ $(TM_P_H) diff --git a/gcc/basic-block.h b/gcc/basic-block.h index eae8e29ac98..58f6aa1fc94 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -174,14 +174,12 @@ typedef struct basic_block_def { /* The index of this block. */ int index; - /* The loop depth of this block plus one. */ - int loop_depth; - /* The active eh region before head and after end. */ - int eh_beg, eh_end; + /* The loop depth of this block. */ + int loop_depth; - int count; /* Expected number of executions: calculated in - profile.c */ + /* Expected number of executions: calculated in profile.c. */ + int count; } *basic_block; /* Number of basic blocks in the current function. */ diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index 93b2034963c..e13e5f14485 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -92,7 +92,6 @@ #include "flags.h" #include "output.h" #include "function.h" -#include "except.h" #include "toplev.h" #include "recog.h" #include "expr.h" @@ -395,8 +394,6 @@ make_reorder_chain_1 (bb, prev) taken = probability > REG_BR_PROB_BASE / 2; /* Find the normal taken edge and the normal fallthru edge. - Note that there may in fact be other edges due to - flag_non_call_exceptions. Note, conditional jumps with other side effects may not be fully optimized. In this case it is possible for @@ -1356,17 +1353,6 @@ reorder_basic_blocks () if (n_basic_blocks <= 1) return; - /* We do not currently handle correct re-placement of EH notes. - But that does not matter unless we intend to use them. */ - if (flag_exceptions) - for (i = 0; i < n_basic_blocks; i++) - { - edge e; - for (e = BASIC_BLOCK (i)->succ; e ; e = e->succ_next) - if (e->flags & EDGE_EH) - return; - } - for (i = 0; i < n_basic_blocks; i++) BASIC_BLOCK (i)->aux = xcalloc (1, sizeof (struct reorder_block_def)); diff --git a/gcc/builtins.c b/gcc/builtins.c index 88127ca7366..eecf1c5a860 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3605,9 +3605,12 @@ expand_builtin (exp, target, subtarget, mode, ignore) return expand_builtin_extract_return_addr (TREE_VALUE (arglist)); case BUILT_IN_EH_RETURN: expand_builtin_eh_return (TREE_VALUE (arglist), - TREE_VALUE (TREE_CHAIN (arglist)), - TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)))); + TREE_VALUE (TREE_CHAIN (arglist))); return const0_rtx; +#ifdef EH_RETURN_DATA_REGNO + case BUILT_IN_EH_RETURN_DATA_REGNO: + return expand_builtin_eh_return_data_regno (arglist); +#endif case BUILT_IN_VARARGS_START: return expand_builtin_va_start (0, arglist); case BUILT_IN_STDARG_START: diff --git a/gcc/builtins.def b/gcc/builtins.def index cd715d9db96..1d59d78f824 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -97,6 +97,7 @@ DEF_BUILTIN(BUILT_IN_INIT_DWARF_REG_SIZES) DEF_BUILTIN(BUILT_IN_FROB_RETURN_ADDR) DEF_BUILTIN(BUILT_IN_EXTRACT_RETURN_ADDR) DEF_BUILTIN(BUILT_IN_EH_RETURN) +DEF_BUILTIN(BUILT_IN_EH_RETURN_DATA_REGNO) DEF_BUILTIN(BUILT_IN_VARARGS_START) DEF_BUILTIN(BUILT_IN_STDARG_START) diff --git a/gcc/c-common.c b/gcc/c-common.c index 3823405aedc..1b00362ba0d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3146,6 +3146,11 @@ c_common_nodes_and_builtins () builtin_function ("__builtin_frame_address", ptr_ftype_unsigned, BUILT_IN_FRAME_ADDRESS, BUILT_IN_NORMAL, NULL_PTR); +#ifdef EH_RETURN_DATA_REGNO + builtin_function ("__builtin_eh_return_data_regno", int_ftype_int, + BUILT_IN_EH_RETURN_DATA_REGNO, BUILT_IN_NORMAL, NULL_PTR); +#endif + builtin_function ("__builtin_alloca", ptr_ftype_sizetype, BUILT_IN_ALLOCA, BUILT_IN_NORMAL, "alloca"); builtin_function_2 ("__builtin_ffs", "ffs", diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 941083236b2..a8c1d300b2b 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3084,12 +3084,11 @@ init_decl_processing () builtin_function ("__builtin_eh_return", build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, + type_for_mode (ptr_mode, 0), tree_cons (NULL_TREE, - type_for_mode (ptr_mode, 0), - tree_cons (NULL_TREE, - ptr_type_node, - endlink)))), + ptr_type_node, + endlink))), BUILT_IN_EH_RETURN, BUILT_IN_NORMAL, NULL_PTR); pedantic_lvalues = pedantic; diff --git a/gcc/calls.c b/gcc/calls.c index 3162b4654a6..228d9b8e112 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -204,7 +204,6 @@ static void compute_argument_addresses PARAMS ((struct arg_data *, static rtx rtx_for_function_call PARAMS ((tree, tree)); static void load_register_parameters PARAMS ((struct arg_data *, int, rtx *, int)); -static int libfunc_nothrow PARAMS ((rtx)); static rtx emit_library_call_value_1 PARAMS ((int, rtx, rtx, enum libcall_type, enum machine_mode, @@ -3444,22 +3443,6 @@ expand_call (exp, target, ignore) return target; } -/* Returns nonzero if FUN is the symbol for a library function which can - not throw. */ - -static int -libfunc_nothrow (fun) - rtx fun; -{ - if (fun == throw_libfunc - || fun == rethrow_libfunc - || fun == sjthrow_libfunc - || fun == sjpopnthrow_libfunc) - return 0; - - return 1; -} - /* Output a library call to function FUN (a SYMBOL_REF rtx). The RETVAL parameter specifies whether return value needs to be saved, other parameters are documented in the emit_library_call function bellow. */ @@ -3501,7 +3484,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) rtx valreg; int pcc_struct_value = 0; int struct_value_size = 0; - int flags = 0; + int flags; int reg_parm_stack_space = 0; int needed; rtx before_call; @@ -3525,6 +3508,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) #endif #endif + /* No library functions can throw. */ + flags = ECF_NOTHROW; + if (fn_type == LCT_CONST_MAKE_BLOCK) flags |= ECF_CONST; else if (fn_type == LCT_PURE_MAKE_BLOCK) @@ -3533,9 +3519,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) flags |= ECF_NORETURN; fun = orgfun; - if (libfunc_nothrow (fun)) - flags |= ECF_NOTHROW; - #ifdef PREFERRED_STACK_BOUNDARY /* Ensure current function's preferred stack boundary is at least what we need. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9540023cb8d..0db7144ee0f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,59 @@ +2001-03-28 Richard Henderson + + IA-64 ABI Exception Handling: + * cp-tree.def (EH_SPEC_BLOCK): New. + (MUST_NOT_THROW_EXPR): New. + * cp-tree.h: Update changed function declarations. + (CPTI_PUSH_EXCEPTION_IDENTIFIER): Remove. + (CPTI_CALL_UNEXPECTED): New. + (struct cp_language_function): Rename x_eh_spec_try_block + to x_eh_spec_block. + (EH_SPEC_STMTS, EH_SPEC_RAISES): New. + * decl.c (current_binding_level): If no current function + bindings, revert to scope_chain. + (initialize_predefined_identifiers): Remove __cp_push_exception. + (store_parm_decls): Use begin_eh_spec_block. + (finish_function): Use finish_eh_spec_block. + (mark_lang_function): Update for name changes. + * decl2.c (finish_file): No mark_all_runtime_matches. + * dump.c (cp_dump_tree): Handle new tree codes. + * error.c (dump_expr) [BIND_EXPR]: Fix typo. + * except.c (catch_language_init, catch_language): Remove. + (init_exception_processing): Don't set language code. + Initialize call_unexpected_node, protect_cleanup_actions, + eh_personality_libfunc, lang_eh_runtime_type. + (call_eh_info, push_eh_info, get_eh_info, get_eh_value): Remove. + (get_eh_type, get_eh_caught, get_eh_handlers): Remove. + (prepare_eh_type): Split out type canonicalizations ... + (build_eh_type_type): ... from here. + (build_eh_type_type_ref): Remove. + (mark_all_runtime_matches): Remove. + (build_exc_ptr): New. + (do_begin_catch, do_end_catch): New. + (do_pop_exception): Remove. + (build_terminate_handler): Remove. + (choose_personality_routine): Split out language choice from ... + (initialize_handler_parm): ... here. + Use MUST_NOT_THROW_EXPR. + (expand_start_catch_block): Use do_begin_catch. Simplify Java + exception object handling. + (expand_start_eh_spec, expand_end_eh_spec): Remove. + (expand_exception_blocks, alloc_eh_object): Remove. + (begin_eh_spec_block, finish_eh_spec_block): New. + (do_allocate_exception, do_free_exception): New. + (expand_throw): Merge into ... + (build_throw): ... here. Update for abi. + * expr.c (cplus_expand_expr): No expand_internal_throw. + Handle MUST_NOT_THROW_EXPR. + * pt.c (tsubst_expr): Handle EH_SPEC_BLOCK. + * semantics.c (*) Update for except.h name changes. + (genrtl_try_block): No protect_with_terminate. + (genrtl_eh_spec_block): New. + (genrtl_handler): Don't emit the goto here. + (cp_expand_stmt): Handle EH_SPEC_BLOCK. + (genrtl_finish_function): Don't expand_exception_blocks. + * tree.c (cp_statement_code_p): Handle EH_SPEC_BLOCK. + 2001-03-28 Richard Henderson * decl.c (struct named_label_list): Rename eh_region to diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 3d514b518b6..5e89189774d 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -236,8 +236,13 @@ DEFTREECODE (START_CATCH_STMT, "start_catch_stmt", 'e', 0) DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2) DEFTREECODE (RETURN_INIT, "return_init", 'e', 2) DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2) +DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2) DEFTREECODE (HANDLER, "handler", 'e', 2) +/* A MUST_NOT_THROW_EXPR wraps an expression that may not + throw, and must call terminate if it does. */ +DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1) + DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0) /* And some codes for expressing conversions for overload resolution. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 91c280c9f42..449a3bda565 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -616,7 +616,6 @@ enum cp_tree_index CPTI_PFN_IDENTIFIER, CPTI_PFN_OR_DELTA2_IDENTIFIER, CPTI_VPTR_IDENTIFIER, - CPTI_PUSH_EXCEPTION_IDENTIFIER, CPTI_STD_IDENTIFIER, CPTI_LANG_NAME_C, @@ -627,6 +626,7 @@ enum cp_tree_index CPTI_NULL, CPTI_JCLASS, CPTI_TERMINATE, + CPTI_CALL_UNEXPECTED, CPTI_ATEXIT, CPTI_DSO_HANDLE, CPTI_DCAST, @@ -740,9 +740,6 @@ extern tree cp_global_trees[CPTI_MAX]; #define pfn_identifier cp_global_trees[CPTI_PFN_IDENTIFIER] #define pfn_or_delta2_identifier cp_global_trees[CPTI_PFN_OR_DELTA2_IDENTIFIER] #define vptr_identifier cp_global_trees[CPTI_VPTR_IDENTIFIER] -/* The name of the function to call to push an exception onto the - exception stack. */ -#define cp_push_exception_identifier cp_global_trees[CPTI_PUSH_EXCEPTION_IDENTIFIER] /* The name of the std namespace. */ #define std_identifier cp_global_trees[CPTI_STD_IDENTIFIER] #define lang_name_c cp_global_trees[CPTI_LANG_NAME_C] @@ -761,6 +758,9 @@ extern tree cp_global_trees[CPTI_MAX]; /* The declaration for `std::terminate'. */ #define terminate_node cp_global_trees[CPTI_TERMINATE] +/* The declaration for "__cxa_call_unexpected". */ +#define call_unexpected_node cp_global_trees[CPTI_CALL_UNEXPECTED] + /* A pointer to `std::atexit'. */ #define atexit_node cp_global_trees[CPTI_ATEXIT] @@ -872,7 +872,7 @@ struct cp_language_function tree x_dtor_label; tree x_current_class_ptr; tree x_current_class_ref; - tree x_eh_spec_try_block; + tree x_eh_spec_block; tree x_in_charge_parm; tree x_vtt_parm; @@ -916,10 +916,10 @@ struct cp_language_function #define current_class_ref \ (cfun ? cp_function_chain->x_current_class_ref : NULL_TREE) -/* The TRY_BLOCK for the exception-specifiers for the current +/* The EH_SPEC_BLOCK for the exception-specifiers for the current function, if any. */ -#define current_eh_spec_try_block cp_function_chain->x_eh_spec_try_block +#define current_eh_spec_block cp_function_chain->x_eh_spec_block /* The `__in_chrg' parameter for the current function. Only used for constructors and destructors. */ @@ -3035,6 +3035,9 @@ extern int flag_new_for_scope; #define TRY_STMTS(NODE) TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 0) #define TRY_HANDLERS(NODE) TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 1) +#define EH_SPEC_STMTS(NODE) TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 0) +#define EH_SPEC_RAISES(NODE) TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 1) + /* Nonzero if this try block is a function try block. */ #define FN_TRY_BLOCK_P(NODE) TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE)) #define HANDLER_PARMS(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 0) @@ -4000,9 +4003,9 @@ extern void init_exception_processing PARAMS ((void)); extern tree expand_start_catch_block PARAMS ((tree)); extern void expand_end_catch_block PARAMS ((tree)); extern void expand_builtin_throw PARAMS ((void)); -extern tree expand_start_eh_spec PARAMS ((void)); -extern void expand_end_eh_spec PARAMS ((tree, tree)); +extern void expand_eh_spec_block PARAMS ((tree)); extern void expand_exception_blocks PARAMS ((void)); +extern tree build_exc_ptr PARAMS ((void)); extern tree build_throw PARAMS ((tree)); extern void mark_all_runtime_matches PARAMS ((void)); extern int nothrow_libfn_p PARAMS ((tree)); @@ -4256,6 +4259,8 @@ extern tree finish_case_label PARAMS ((tree, tree)); extern tree finish_goto_stmt PARAMS ((tree)); extern tree begin_try_block PARAMS ((void)); extern void finish_try_block PARAMS ((tree)); +extern tree begin_eh_spec_block PARAMS ((void)); +extern void finish_eh_spec_block PARAMS ((tree, tree)); extern void finish_handler_sequence PARAMS ((tree)); extern tree begin_function_try_block PARAMS ((void)); extern void finish_function_try_block PARAMS ((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 366d37c38bd..b96545dc91a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -478,7 +478,7 @@ struct binding_level /* The binding level currently in effect. */ #define current_binding_level \ - (cfun \ + (cfun && cp_function_chain->bindings \ ? cp_function_chain->bindings \ : scope_chain->bindings) @@ -6306,7 +6306,6 @@ initialize_predefined_identifiers () { VTABLE_PFN_NAME, &pfn_identifier, 0 }, { "__pfn_or_delta2", &pfn_or_delta2_identifier, 0 }, { "_vptr", &vptr_identifier, 0 }, - { "__cp_push_exception", &cp_push_exception_identifier, 0 }, { "__vtt_parm", &vtt_parm_identifier, 0 }, { "std", &std_identifier, 0 }, { NULL, NULL, 0 } @@ -13721,7 +13720,7 @@ store_parm_decls (current_function_parms) if (flag_exceptions && !processing_template_decl && flag_enforce_eh_specs && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) - current_eh_spec_try_block = expand_start_eh_spec (); + current_eh_spec_block = begin_eh_spec_block (); } @@ -13966,9 +13965,9 @@ finish_function (flags) if (flag_exceptions && !processing_template_decl && flag_enforce_eh_specs && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) - expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS - (TREE_TYPE (current_function_decl)), - current_eh_spec_try_block); + finish_eh_spec_block (TYPE_RAISES_EXCEPTIONS + (TREE_TYPE (current_function_decl)), + current_eh_spec_block); } /* If we're saving up tree structure, tie off the function now. */ @@ -14395,7 +14394,7 @@ mark_lang_function (p) ggc_mark_tree (p->x_dtor_label); ggc_mark_tree (p->x_current_class_ptr); ggc_mark_tree (p->x_current_class_ref); - ggc_mark_tree (p->x_eh_spec_try_block); + ggc_mark_tree (p->x_eh_spec_block); ggc_mark_tree_varray (p->x_local_names); mark_named_label_lists (&p->x_named_labels, &p->x_named_label_uses); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a8300b9fc9a..35c8ca77e9e 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3621,10 +3621,6 @@ finish_file () } } - /* Mark all functions that might deal with exception-handling as - referenced. */ - mark_all_runtime_matches (); - /* We lie to the back-end, pretending that some functions are not defined when they really are. This keeps these functions from being put out unnecessarily. But, we must stop lying diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index a0982a616b2..a4033c3db53 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -188,6 +188,13 @@ cp_dump_tree (di, t) dump_next_stmt (di, t); break; + case EH_SPEC_BLOCK: + dump_stmt (di, t); + dump_child ("body", EH_SPEC_STMTS (t)); + dump_child ("raises", EH_SPEC_RAISES (t)); + dump_next_stmt (di, t); + break; + case PTRMEM_CST: dump_child ("clas", PTRMEM_CST_CLASS (t)); dump_child ("mbr", PTRMEM_CST_MEMBER (t)); @@ -227,6 +234,12 @@ cp_dump_tree (di, t) dump_next_stmt (di, t); break; + case MUST_NOT_THROW_EXPR: + dump_stmt (di, t); + dump_child ("body", TREE_OPERAND (t, 0)); + dump_next_stmt (di, t); + break; + case SUBOBJECT: dump_stmt (di, t); dump_child ("clnp", TREE_OPERAND (t, 0)); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index feb47365467..7d2f1fab7cd 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2104,7 +2104,7 @@ dump_expr (t, flags) break; case BIND_EXPR: - output_add_character (scratch_buffer, '}'); + output_add_character (scratch_buffer, '{'); dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); output_add_character (scratch_buffer, '}'); break; diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 4f5bde6a2a9..600a21abd3f 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -34,299 +34,67 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "except.h" #include "toplev.h" -#include "eh-common.h" static void push_eh_cleanup PARAMS ((tree)); +static tree prepare_eh_type PARAMS ((tree)); static tree build_eh_type_type PARAMS ((tree)); -static tree call_eh_info PARAMS ((void)); -static void push_eh_info PARAMS ((void)); -static tree get_eh_info PARAMS ((void)); -static tree get_eh_value PARAMS ((void)); -#if 0 -static tree get_eh_type PARAMS ((void)); -static tree get_eh_caught PARAMS ((void)); -static tree get_eh_handlers PARAMS ((void)); -#endif +static tree do_begin_catch PARAMS ((void)); static int dtor_nothrow PARAMS ((tree)); -static tree do_pop_exception PARAMS ((tree)); -static tree build_eh_type_type_ref PARAMS ((tree)); -static tree build_terminate_handler PARAMS ((void)); -static tree alloc_eh_object PARAMS ((tree)); +static tree do_end_catch PARAMS ((tree)); +static void push_eh_cleanup PARAMS ((tree)); +static bool decl_is_java_type PARAMS ((tree decl, int err)); +static void choose_personality_routine PARAMS ((bool)); +static void initialize_handler_parm PARAMS ((tree, tree)); +static tree do_allocate_exception PARAMS ((tree)); +static tree do_free_exception PARAMS ((tree)); static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree)); static bool is_admissible_throw_operand PARAMS ((tree)); static int can_convert_eh PARAMS ((tree, tree)); static void check_handlers_1 PARAMS ((tree, tree)); -static void initialize_handler_parm PARAMS ((tree)); -static tree expand_throw PARAMS ((tree)); -static int decl_is_java_type PARAMS ((tree decl, int err)); #include "decl.h" #include "obstack.h" -/* In a given translation unit we are constrained to catch only C++ - types or only Java types. `catch_language' holds the current type, - and `catch_language_init' registers whether `catch_language' has - been set. */ - -static int catch_language_init = 0; -static int catch_language; - -/* ====================================================================== - Briefly the algorithm works like this: - - When a constructor or start of a try block is encountered, - push_eh_entry (&eh_stack) is called. Push_eh_entry () creates a - new entry in the unwind protection stack and returns a label to - output to start the protection for that block. - - When a destructor or end try block is encountered, pop_eh_entry - (&eh_stack) is called. Pop_eh_entry () returns the eh_entry it - created when push_eh_entry () was called. The eh_entry structure - contains three things at this point. The start protect label, - the end protect label, and the exception handler label. The end - protect label should be output before the call to the destructor - (if any). If it was a destructor, then its parse tree is stored - in the finalization variable in the eh_entry structure. Otherwise - the finalization variable is set to NULL to reflect the fact that - it is the end of a try block. Next, this modified eh_entry node - is enqueued in the finalizations queue by calling - enqueue_eh_entry (&queue,entry). - - +---------------------------------------------------------------+ - |XXX: Will need modification to deal with partially | - | constructed arrays of objects | - | | - | Basically, this consists of keeping track of how many | - | of the objects have been constructed already (this | - | should be in a register though, so that shouldn't be a | - | problem. | - +---------------------------------------------------------------+ - - When a catch block is encountered, there is a lot of work to be - done. - - Since we don't want to generate the catch block inline with the - regular flow of the function, we need to have some way of doing - so. Luckily, we can use sequences to defer the catch sections. - When the start of a catch block is encountered, we start the - sequence. After the catch block is generated, we end the - sequence. - - Next we must insure that when the catch block is executed, all - finalizations for the matching try block have been completed. If - any of those finalizations throw an exception, we must call - terminate according to the ARM (section r.15.6.1). What this - means is that we need to dequeue and emit finalizations for each - entry in the eh_queue until we get to an entry with a NULL - finalization field. For any of the finalization entries, if it - is not a call to terminate (), we must protect it by giving it - another start label, end label, and exception handler label, - setting its finalization tree to be a call to terminate (), and - enqueue'ing this new eh_entry to be output at an outer level. - Finally, after all that is done, we can get around to outputting - the catch block which basically wraps all the "catch (...) {...}" - statements in a big if/then/else construct that matches the - correct block to call. - - ===================================================================== */ - -/* ====================================================================== */ - -/* sets up all the global eh stuff that needs to be initialized at the +/* Sets up all the global eh stuff that needs to be initialized at the start of compilation. */ void init_exception_processing () { - /* void vtype () */ - tree vtype = build_function_type (void_type_node, void_list_node); - + tree tmp; + if (flag_honor_std) push_namespace (std_identifier); - terminate_node = build_cp_library_fn_ptr ("terminate", vtype); + + /* void std::terminate (); */ + tmp = build_function_type (void_type_node, void_list_node); + terminate_node = build_cp_library_fn_ptr ("terminate", tmp); TREE_THIS_VOLATILE (terminate_node) = 1; TREE_NOTHROW (terminate_node) = 1; if (flag_honor_std) pop_namespace (); - set_exception_lang_code (EH_LANG_C_plus_plus); - set_exception_version_code (1); - - /* If we use setjmp/longjmp EH, arrange for all cleanup actions to - be protected with __terminate. */ - protect_cleanup_actions_with_terminate = 1; -} - -/* Retrieve a pointer to the cp_eh_info node for the current exception. */ - -static tree -call_eh_info () -{ - tree fn; - - fn = get_identifier ("__start_cp_handler"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - tree eh_info_type; - tree cleanup_fn_type; - tree matcher_fn_type; - tree cp_eh_info_type; - tree exception_desc_type; - tree fields[8]; - - eh_info_type = make_aggr_type (RECORD_TYPE); - exception_desc_type = make_aggr_type (RECORD_TYPE); - - /* void * (*) (__eh_info *, void *, exception_descriptor *); */ - matcher_fn_type = tree_cons - (NULL_TREE, build_pointer_type (eh_info_type), tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, build_pointer_type (exception_desc_type), - void_list_node))); - matcher_fn_type = build_function_type (ptr_type_node, matcher_fn_type); - matcher_fn_type = build_pointer_type (matcher_fn_type); - - /* void (*) (void *); */ - cleanup_fn_type = tree_cons - (NULL_TREE, ptr_type_node, void_list_node); - cleanup_fn_type = build_function_type (void_type_node, cleanup_fn_type); - cleanup_fn_type = build_pointer_type (cleanup_fn_type); - - /* eh-common.h - struct __eh_info - { - __eh_matcher match_function; - short language; - short version; - }; */ - fields[0] = build_decl (FIELD_DECL, - get_identifier ("match_function"), ptr_type_node); - fields[1] = build_decl (FIELD_DECL, - get_identifier ("language"), short_integer_type_node); - fields[2] = build_decl (FIELD_DECL, - get_identifier ("version"), short_integer_type_node); - /* N.B.: The fourth field LEN is expected to be - the number of fields - 1, not the total number of fields. */ - finish_builtin_type (eh_info_type, "__eh_info", fields, 2, ptr_type_node); - - /* exception_support.h - struct cp_eh_info - { - __eh_info eh_info; - void *value; - void *type; - cleanup_fn cleanup; - bool caught; - cp_eh_info *next; - long handlers; - void *original_value; - }; */ - cp_eh_info_type = make_aggr_type (RECORD_TYPE); - fields[0] = build_decl (FIELD_DECL, get_identifier ("eh_info"), - eh_info_type); - fields[1] = build_decl (FIELD_DECL, get_identifier ("value"), - ptr_type_node); - fields[2] = build_decl (FIELD_DECL, get_identifier ("type"), - ptr_type_node); - fields[3] = build_decl (FIELD_DECL, get_identifier ("cleanup"), - cleanup_fn_type); - fields[4] = build_decl (FIELD_DECL, get_identifier ("caught"), - boolean_type_node); - fields[5] = build_decl (FIELD_DECL, get_identifier ("next"), - build_pointer_type (cp_eh_info_type)); - fields[6] = build_decl (FIELD_DECL, get_identifier ("handlers"), - long_integer_type_node); - fields[7] = build_decl (FIELD_DECL, get_identifier ("original_value"), - ptr_type_node); - /* N.B.: The fourth field LEN is expected to be - the number of fields - 1, not the total number of fields. */ - finish_builtin_type (cp_eh_info_type, "cp_eh_info", fields, 7, ptr_type_node); - - /* And now the function. */ - fn = push_library_fn (fn, - build_function_type (build_pointer_type (cp_eh_info_type), - void_list_node)); - } - return build_function_call (fn, NULL_TREE); -} - -/* Retrieve a pointer to the cp_eh_info node for the current exception - and save it in the current binding level. */ - -static void -push_eh_info () -{ - tree decl, fn = call_eh_info (); - - /* Remember the pointer to the current exception info; it won't change - during this catch block. */ - decl = build_decl (VAR_DECL, get_identifier ("__exception_info"), - TREE_TYPE (fn)); - DECL_ARTIFICIAL (decl) = 1; - DECL_INITIAL (decl) = fn; - decl = pushdecl (decl); - cp_finish_decl (decl, fn, NULL_TREE, 0); -} - -/* Returns a reference to the cp_eh_info node for the current exception. */ - -static tree -get_eh_info () -{ - /* Look for the pointer pushed in push_eh_info. */ - tree t = lookup_name (get_identifier ("__exception_info"), 0); - return build_indirect_ref (t, NULL_PTR); -} - -/* Returns a reference to the current exception object. */ + protect_cleanup_actions = build_call (terminate_node, NULL_TREE); -static tree -get_eh_value () -{ - return build_component_ref (get_eh_info (), get_identifier ("value"), - NULL_TREE, 0); -} + /* void __cxa_call_unexpected(void *); */ + tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node); + tmp = build_function_type (void_type_node, tmp); + call_unexpected_node + = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp); -/* Returns a reference to the current exception type. */ + eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS + ? "__gxx_personality_sj0" + : "__gxx_personality_v0"); -#if 0 -static tree -get_eh_type () -{ - return build_component_ref (get_eh_info (), get_identifier ("type"), - NULL_TREE, 0); + lang_eh_runtime_type = build_eh_type_type; } -/* Returns a reference to whether or not the current exception - has been caught. */ - static tree -get_eh_caught () -{ - return build_component_ref (get_eh_info (), get_identifier ("caught"), - NULL_TREE, 0); -} - -/* Returns a reference to whether or not the current exception - has been caught. */ - -static tree -get_eh_handlers () -{ - return build_component_ref (get_eh_info (), get_identifier ("handlers"), - NULL_TREE, 0); -} -#endif - -/* Build a type value for use at runtime for a type that is matched - against by the exception handling system. */ - -static tree -build_eh_type_type (type) +prepare_eh_type (type) tree type; { + if (type == NULL_TREE) + return type; if (type == error_mark_node) return error_mark_node; @@ -337,14 +105,14 @@ build_eh_type_type (type) /* Peel off cv qualifiers. */ type = TYPE_MAIN_VARIANT (type); - return build1 (ADDR_EXPR, ptr_type_node, get_typeid_1 (type)); + return type; } /* Build the address of a typeinfo decl for use in the runtime - matching field of the new exception model */ + matching field of the exception model. */ static tree -build_eh_type_type_ref (type) +build_eh_type_type (type) tree type; { tree exp; @@ -352,47 +120,43 @@ build_eh_type_type_ref (type) if (type == NULL_TREE || type == error_mark_node) return type; - /* peel back references, so they match. */ - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* Peel off cv qualifiers. */ - type = TYPE_MAIN_VARIANT (type); + if (decl_is_java_type (type, 0)) + exp = build_java_class_ref (TREE_TYPE (type)); + else + exp = get_tinfo_decl (type); - exp = get_tinfo_decl (type); mark_used (exp); exp = build1 (ADDR_EXPR, ptr_type_node, exp); - return (exp); + return exp; +} + +tree +build_exc_ptr () +{ + return build (EXC_PTR_EXPR, ptr_type_node); } -/* This routine is called to mark all the symbols representing runtime - type functions in the exception table as having been referenced. - This will make sure code is emitted for them. Called from finish_file. */ +/* Build up a call to __cxa_begin_catch, to tell the runtime that the + exception has been handled. */ -void -mark_all_runtime_matches () +static tree +do_begin_catch () { - int x,num; - void **ptr; - tree exp; - - num = find_all_handler_type_matches (&ptr); - if (num == 0 || ptr == NULL) - return; - - for (x=0; x dw_cfi_next) output_cfi (cfi, NULL); /* Pad the CIE out to an address sized boundary. */ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DWARF2_ADDR_SIZE)); ASM_OUTPUT_LABEL (asm_out_file, l2); -#ifdef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL - ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL (asm_out_file, ld, l2, l1); - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s CIE Length Symbol", ASM_COMMENT_START); - fputc ('\n', asm_out_file); -#endif /* Loop through all of the FDE's. */ for (i = 0; i < fde_table_in_use; ++i) { fde = &fde_table[i]; - /* Don't emit EH unwind info for leaf functions. */ - if (for_eh && fde->nothrow) + /* Don't emit EH unwind info for leaf functions that don't need it. */ + if (for_eh && fde->nothrow && ! fde->uses_eh_lsda) continue; ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2); -#ifdef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL - ASM_GENERATE_INTERNAL_LABEL (ld, FDE_LENGTH_LABEL, for_eh + i * 2); - dw2_asm_output_offset (for_eh ? 4 : DWARF_OFFSET_SIZE, ld, "FDE Length"); -#else dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, "FDE Length"); -#endif ASM_OUTPUT_LABEL (asm_out_file, l1); /* ??? This always emits a 4 byte offset when for_eh is true, but it @@ -1821,6 +1820,21 @@ output_call_frame_info (for_eh) dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_end, fde->dw_fde_begin, "FDE address range"); + if (augmentation[0]) + { + dw2_asm_output_data_uleb128 (DWARF2_ADDR_SIZE, "Augmentation size"); + + if (fde->uses_eh_lsda) + { + ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA", fde->funcdef_number); + dw2_asm_output_offset (DWARF2_ADDR_SIZE, l1, + "Language Specific Data Area"); + } + else + dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, + "Language Specific Data Area (none)"); + } + /* Loop through the Call Frame Instructions associated with this FDE. */ fde->dw_fde_current_label = fde->dw_fde_begin; @@ -1830,12 +1844,6 @@ output_call_frame_info (for_eh) /* Pad the FDE out to an address sized boundary. */ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DWARF2_ADDR_SIZE)); ASM_OUTPUT_LABEL (asm_out_file, l2); -#ifdef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL - ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL (asm_out_file, ld, l2, l1); - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s FDE Length Symbol", ASM_COMMENT_START); - fputc ('\n', asm_out_file); -#endif } #ifndef EH_FRAME_SECTION @@ -1888,7 +1896,9 @@ dwarf2out_begin_prologue () fde->dw_fde_current_label = NULL; fde->dw_fde_end = NULL; fde->dw_fde_cfi = NULL; + fde->funcdef_number = current_funcdef_number; fde->nothrow = current_function_nothrow; + fde->uses_eh_lsda = cfun->uses_eh_lsda; args_size = old_args_size = 0; } diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index a48dbf8e864..1f42626a066 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -41,3 +41,5 @@ extern void debug_dwarf_die PARAMS ((struct die_struct *)); extern void dwarf2out_set_demangle_name_func PARAMS ((const char *(*) (const char *))); extern void dwarf2out_abstract_function PARAMS ((tree)); extern void dwarf2out_add_library_unit_info PARAMS ((const char *, const char *)); + +extern unsigned current_funcdef_number; diff --git a/gcc/eh-common.h b/gcc/eh-common.h deleted file mode 100644 index dffe682a05b..00000000000 --- a/gcc/eh-common.h +++ /dev/null @@ -1,162 +0,0 @@ -/* EH stuff - Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - -This file is part of GNU CC. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -/* This file contains the structures required for the language - independent exception handling model. Both the static compiler and - the runtime library share this file. */ - -/* The runtime flag flag_new_exceptions is used to determine whether the - compiler supports the new runtime typechecking mechanism or not. Under - the new model, runtime info is contained in the exception table, and - the __throw() library routine determines which handler to call based - on the results of a call to a matching function provided by the expcetion - thrower. Otherwise the old scheme of calling any handler which matches - an exception range is used, and the handler is responsible for all - checking of runtime conditions. If the handler wasn't suppose to - get the exception, it performs a re-throw. */ - - -/* The handler_label field MUST be the first field in this structure. The - __throw() library routine expects uses __eh_stub() from except.c, which - simply dereferences the context pointer to get the handler. - The routine get_dynamic_handler_chain() also has a dependancy on - the location of 'dynamic_handler_chain'. If its location is changed, - that routine must be modified as well. */ -#ifndef EH_ALLOC_SIZE -/* 192 bytes means the entire eh_context plus malloc overhead fits in 256 - bytes (assuming 8 byte pointers). 192 bytes gives an eh_info and object - size limit of 96 bytes. This should be sufficient for throwing bad_alloc. */ -#define EH_ALLOC_SIZE 192 -#endif -#ifndef EH_ALLOC_ALIGN -/* We can't use BIGGEST_ALIGNMENT, because on some systems, that expands to - a check on a compile time switch like - 'target_flags & MASK_ALIGN_DOUBLE ? 64 : 32'. There's no macro for - 'largest alignment for any code this compiler can build for', which is - really what is needed. */ -#define EH_ALLOC_ALIGN 16 -#endif - -struct eh_context -{ - void *handler_label; - void **dynamic_handler_chain; - /* This is language dependent part of the eh context. */ - void *info; - /* This is used to remember where we threw for re-throws */ - void *table_index; /* address of exception table entry to rethrow from */ - /* emergency fallback space, if malloc fails during handling */ - char alloc_buffer[EH_ALLOC_SIZE] - __attribute__((__aligned__(EH_ALLOC_ALIGN))); - unsigned alloc_mask; -}; - -#ifndef EH_TABLE_LOOKUP - -typedef struct old_exception_table -{ - void *start_region; - void *end_region; - void *exception_handler; -} old_exception_table; - -typedef struct exception_table -{ - void *start_region; - void *end_region; - void *exception_handler; - void *match_info; /* runtime type info */ -} exception_table; - - -/* The language identifying portion of an exception table */ - -typedef struct exception_lang_info -{ - short language; - short version; -} exception_lang_info; - -/* This value in the first field of the exception descriptor - identifies the descriptor as the new model format. This value would never - be present in this location under the old model */ - -#define NEW_EH_RUNTIME ((void *) -2) - -/* Each function has an exception_descriptor which contains the - language info, and a table of exception ranges and handlers */ - -typedef struct exception_descriptor -{ - void *runtime_id_field; - exception_lang_info lang; - exception_table table[1]; -} exception_descriptor; - -struct __eh_info; /* forward declaration */ - -/* A pointer to a matching function is initialized at runtime by the - specific language if run-time exceptions are supported. - The function takes 3 parameters - 1 - runtime exception that has been thrown info. (__eh_info *) - 2 - Match info pointer from the region being considered (void *) - 3 - exception table region is in (exception descriptor *) -*/ - -typedef void * (*__eh_matcher) PARAMS ((struct __eh_info *, void *, - struct exception_descriptor *)); - -/* This value is to be checked as a 'match all' case in the runtime field. */ - -#define CATCH_ALL_TYPE ((void *) -1) - -/* This is the runtime exception information. This forms the minimum required - information for an exception info pointer in an eh_context structure. */ - - -typedef struct __eh_info -{ - __eh_matcher match_function; - short language; - short version; -} __eh_info; - -/* Convienient language codes for ID the originating language. Similar - to the codes in dwarf2.h. */ - -enum exception_source_language - { - EH_LANG_C89 = 0x0001, - EH_LANG_C = 0x0002, - EH_LANG_Ada83 = 0x0003, - EH_LANG_C_plus_plus = 0x0004, - EH_LANG_Cobol74 = 0x0005, - EH_LANG_Cobol85 = 0x0006, - EH_LANG_Fortran77 = 0x0007, - EH_LANG_Fortran90 = 0x0008, - EH_LANG_Pascal83 = 0x0009, - EH_LANG_Modula2 = 0x000a, - EH_LANG_Java = 0x000b, - EH_LANG_Mips_Assembler = 0x8001 - }; - -#endif /* EH_TABLE_LOOKUP */ - - diff --git a/gcc/except.c b/gcc/except.c index bc865552554..ec13ed04437 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -44,1070 +44,935 @@ Boston, MA 02111-1307, USA. */ exception, and thus there is the concept of "throwing" the exception up the call stack. - There are two major codegen options for exception handling. The - flag -fsjlj-exceptions can be used to select the setjmp/longjmp - approach, which is the default. -fno-sjlj-exceptions can be used to - get the PC range table approach. While this is a compile time - flag, an entire application must be compiled with the same codegen - option. The first is a PC range table approach, the second is a - setjmp/longjmp based scheme. We will first discuss the PC range - table approach, after that, we will discuss the setjmp/longjmp - based approach. - - It is appropriate to speak of the "context of a throw". This - context refers to the address where the exception is thrown from, - and is used to determine which exception region will handle the - exception. - - Regions of code within a function can be marked such that if it - contains the context of a throw, control will be passed to a - designated "exception handler". These areas are known as "exception - regions". Exception regions cannot overlap, but they can be nested - to any arbitrary depth. Also, exception regions cannot cross - function boundaries. - - Exception handlers can either be specified by the user (which we - will call a "user-defined handler") or generated by the compiler - (which we will designate as a "cleanup"). Cleanups are used to - perform tasks such as destruction of objects allocated on the - stack. - - In the current implementation, cleanups are handled by allocating an - exception region for the area that the cleanup is designated for, - and the handler for the region performs the cleanup and then - rethrows the exception to the outer exception region. From the - standpoint of the current implementation, there is little - distinction made between a cleanup and a user-defined handler, and - the phrase "exception handler" can be used to refer to either one - equally well. (The section "Future Directions" below discusses how - this will change). - - Each object file that is compiled with exception handling contains - a static array of exception handlers named __EXCEPTION_TABLE__. - Each entry contains the starting and ending addresses of the - exception region, and the address of the handler designated for - that region. - - If the target does not use the DWARF 2 frame unwind information, at - program startup each object file invokes a function named - __register_exceptions with the address of its local - __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c, and - is responsible for recording all of the exception regions into one list - (which is kept in a static variable named exception_table_list). - - On targets that support crtstuff.c, the unwind information - is stored in a section named .eh_frame and the information for the - entire shared object or program is registered with a call to - __register_frame_info. On other targets, the information for each - translation unit is registered from the file generated by collect2. - __register_frame_info is defined in frame.c, and is responsible for - recording all of the unwind regions into one list (which is kept in a - static variable named unwind_table_list). - - The function __throw is actually responsible for doing the - throw. On machines that have unwind info support, __throw is generated - by code in libgcc2.c, otherwise __throw is generated on a - per-object-file basis for each source file compiled with - -fexceptions by the C++ frontend. Before __throw is invoked, - the current context of the throw needs to be placed in the global - variable __eh_pc. - - __throw attempts to find the appropriate exception handler for the - PC value stored in __eh_pc by calling __find_first_exception_table_match - (which is defined in libgcc2.c). If __find_first_exception_table_match - finds a relevant handler, __throw transfers control directly to it. - - If a handler for the context being thrown from can't be found, __throw - walks (see Walking the stack below) the stack up the dynamic call chain to - continue searching for an appropriate exception handler based upon the - caller of the function it last sought a exception handler for. It stops - then either an exception handler is found, or when the top of the - call chain is reached. - - If no handler is found, an external library function named - __terminate is called. If a handler is found, then we restart - our search for a handler at the end of the call chain, and repeat - the search process, but instead of just walking up the call chain, - we unwind the call chain as we walk up it. - - Internal implementation details: - - To associate a user-defined handler with a block of statements, the - function expand_start_try_stmts is used to mark the start of the - block of statements with which the handler is to be associated - (which is known as a "try block"). All statements that appear - afterwards will be associated with the try block. - - A call to expand_start_all_catch marks the end of the try block, - and also marks the start of the "catch block" (the user-defined - handler) associated with the try block. - - This user-defined handler will be invoked for *every* exception - thrown with the context of the try block. It is up to the handler - to decide whether or not it wishes to handle any given exception, - as there is currently no mechanism in this implementation for doing - this. (There are plans for conditionally processing an exception - based on its "type", which will provide a language-independent - mechanism). - - If the handler chooses not to process the exception (perhaps by - looking at an "exception type" or some other additional data - supplied with the exception), it can fall through to the end of the - handler. expand_end_all_catch and expand_leftover_cleanups - add additional code to the end of each handler to take care of - rethrowing to the outer exception handler. - - The handler also has the option to continue with "normal flow of - code", or in other words to resume executing at the statement - immediately after the end of the exception region. The variable - caught_return_label_stack contains a stack of labels, and jumping - to the topmost entry's label via expand_goto will resume normal - flow to the statement immediately after the end of the exception - region. If the handler falls through to the end, the exception will - be rethrown to the outer exception region. - - The instructions for the catch block are kept as a separate - sequence, and will be emitted at the end of the function along with - the handlers specified via expand_eh_region_end. The end of the - catch block is marked with expand_end_all_catch. - - Any data associated with the exception must currently be handled by - some external mechanism maintained in the frontend. For example, - the C++ exception mechanism passes an arbitrary value along with - the exception, and this is handled in the C++ frontend by using a - global variable to hold the value. (This will be changing in the - future.) - - The mechanism in C++ for handling data associated with the - exception is clearly not thread-safe. For a thread-based - environment, another mechanism must be used (possibly using a - per-thread allocation mechanism if the size of the area that needs - to be allocated isn't known at compile time.) - - Internally-generated exception regions (cleanups) are marked by - calling expand_eh_region_start to mark the start of the region, - and expand_eh_region_end (handler) is used to both designate the - end of the region and to associate a specified handler/cleanup with - the region. The rtl code in HANDLER will be invoked whenever an - exception occurs in the region between the calls to - expand_eh_region_start and expand_eh_region_end. After HANDLER is - executed, additional code is emitted to handle rethrowing the - exception to the outer exception handler. The code for HANDLER will - be emitted at the end of the function. - - TARGET_EXPRs can also be used to designate exception regions. A - TARGET_EXPR gives an unwind-protect style interface commonly used - in functional languages such as LISP. The associated expression is - evaluated, and whether or not it (or any of the functions that it - calls) throws an exception, the protect expression is always - invoked. This implementation takes care of the details of - associating an exception table entry with the expression and - generating the necessary code (it actually emits the protect - expression twice, once for normal flow and once for the exception - case). As for the other handlers, the code for the exception case - will be emitted at the end of the function. - - Cleanups can also be specified by using add_partial_entry (handler) - and end_protect_partials. add_partial_entry creates the start of - a new exception region; HANDLER will be invoked if an exception is - thrown with the context of the region between the calls to - add_partial_entry and end_protect_partials. end_protect_partials is - used to mark the end of these regions. add_partial_entry can be - called as many times as needed before calling end_protect_partials. - However, end_protect_partials should only be invoked once for each - group of calls to add_partial_entry as the entries are queued - and all of the outstanding entries are processed simultaneously - when end_protect_partials is invoked. Similarly to the other - handlers, the code for HANDLER will be emitted at the end of the - function. - - The generated RTL for an exception region includes - NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark - the start and end of the exception region. A unique label is also - generated at the start of the exception region, which is available - by looking at the ehstack variable. The topmost entry corresponds - to the current region. - - In the current implementation, an exception can only be thrown from - a function call (since the mechanism used to actually throw an - exception involves calling __throw). If an exception region is - created but no function calls occur within that region, the region - can be safely optimized away (along with its exception handlers) - since no exceptions can ever be caught in that region. This - optimization is performed unless -fasynchronous-exceptions is - given. If the user wishes to throw from a signal handler, or other - asynchronous place, -fasynchronous-exceptions should be used when - compiling for maximally correct code, at the cost of additional - exception regions. Using -fasynchronous-exceptions only produces - code that is reasonably safe in such situations, but a correct - program cannot rely upon this working. It can be used in failsafe - code, where trying to continue on, and proceeding with potentially - incorrect results is better than halting the program. - - - Walking the stack: - - The stack is walked by starting with a pointer to the current - frame, and finding the pointer to the callers frame. The unwind info - tells __throw how to find it. - - Unwinding the stack: - - When we use the term unwinding the stack, we mean undoing the - effects of the function prologue in a controlled fashion so that we - still have the flow of control. Otherwise, we could just return - (jump to the normal end of function epilogue). - - This is done in __throw in libgcc2.c when we know that a handler exists - in a frame higher up the call stack than its immediate caller. - - To unwind, we find the unwind data associated with the frame, if any. - If we don't find any, we call the library routine __terminate. If we do - find it, we use the information to copy the saved register values from - that frame into the register save area in the frame for __throw, return - into a stub which updates the stack pointer, and jump to the handler. - The normal function epilogue for __throw handles restoring the saved - values into registers. - - When unwinding, we use this method if we know it will - work (if DWARF2_UNWIND_INFO is defined). Otherwise, we know that - an inline unwinder will have been emitted for any function that - __unwind_function cannot unwind. The inline unwinder appears as a - normal exception handler for the entire function, for any function - that we know cannot be unwound by __unwind_function. We inform the - compiler of whether a function can be unwound with - __unwind_function by having DOESNT_NEED_UNWINDER evaluate to true - when the unwinder isn't needed. __unwind_function is used as an - action of last resort. If no other method can be used for - unwinding, __unwind_function is used. If it cannot unwind, it - should call __terminate. - - By default, if the target-specific backend doesn't supply a definition - for __unwind_function and doesn't support DWARF2_UNWIND_INFO, inlined - unwinders will be used instead. The main tradeoff here is in text space - utilization. Obviously, if inline unwinders have to be generated - repeatedly, this uses much more space than if a single routine is used. - - However, it is simply not possible on some platforms to write a - generalized routine for doing stack unwinding without having some - form of additional data associated with each function. The current - implementation can encode this data in the form of additional - machine instructions or as static data in tabular form. The later - is called the unwind data. - - The backend macro DOESNT_NEED_UNWINDER is used to conditionalize whether - or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER is - defined and has a non-zero value, a per-function unwinder is not emitted - for the current function. If the static unwind data is supported, then - a per-function unwinder is not emitted. - - On some platforms it is possible that neither __unwind_function - nor inlined unwinders are available. For these platforms it is not - possible to throw through a function call, and abort will be - invoked instead of performing the throw. - - The reason the unwind data may be needed is that on some platforms - the order and types of data stored on the stack can vary depending - on the type of function, its arguments and returned values, and the - compilation options used (optimization versus non-optimization, - -fomit-frame-pointer, processor variations, etc). - - Unfortunately, this also means that throwing through functions that - aren't compiled with exception handling support will still not be - possible on some platforms. This problem is currently being - investigated, but no solutions have been found that do not imply - some unacceptable performance penalties. - - Future directions: - - Currently __throw makes no differentiation between cleanups and - user-defined exception regions. While this makes the implementation - simple, it also implies that it is impossible to determine if a - user-defined exception handler exists for a given exception without - completely unwinding the stack in the process. This is undesirable - from the standpoint of debugging, as ideally it would be possible - to trap unhandled exceptions in the debugger before the process of - unwinding has even started. - - This problem can be solved by marking user-defined handlers in a - special way (probably by adding additional bits to exception_table_list). - A two-pass scheme could then be used by __throw to iterate - through the table. The first pass would search for a relevant - user-defined handler for the current context of the throw, and if - one is found, the second pass would then invoke all needed cleanups - before jumping to the user-defined handler. - - Many languages (including C++ and Ada) make execution of a - user-defined handler conditional on the "type" of the exception - thrown. (The type of the exception is actually the type of the data - that is thrown with the exception.) It will thus be necessary for - __throw to be able to determine if a given user-defined - exception handler will actually be executed, given the type of - exception. - - One scheme is to add additional information to exception_table_list - as to the types of exceptions accepted by each handler. __throw - can do the type comparisons and then determine if the handler is - actually going to be executed. - - There is currently no significant level of debugging support - available, other than to place a breakpoint on __throw. While - this is sufficient in most cases, it would be helpful to be able to - know where a given exception was going to be thrown to before it is - actually thrown, and to be able to choose between stopping before - every exception region (including cleanups), or just user-defined - exception regions. This should be possible to do in the two-pass - scheme by adding additional labels to __throw for appropriate - breakpoints, and additional debugger commands could be added to - query various state variables to determine what actions are to be - performed next. - - Another major problem that is being worked on is the issue with stack - unwinding on various platforms. Currently the only platforms that have - support for the generation of a generic unwinder are the SPARC and MIPS. - All other ports require per-function unwinders, which produce large - amounts of code bloat. - - For setjmp/longjmp based exception handling, some of the details - are as above, but there are some additional details. This section - discusses the details. - - We don't use NOTE_INSN_EH_REGION_{BEG,END} pairs. We don't - optimize EH regions yet. We don't have to worry about machine - specific issues with unwinding the stack, as we rely upon longjmp - for all the machine specific details. There is no variable context - of a throw, just the one implied by the dynamic handler stack - pointed to by the dynamic handler chain. There is no exception - table, and no calls to __register_exceptions. __sjthrow is used - instead of __throw, and it works by using the dynamic handler - chain, and longjmp. -fasynchronous-exceptions has no effect, as - the elimination of trivial exception regions is not yet performed. - - A frontend can set protect_cleanup_actions_with_terminate when all - the cleanup actions should be protected with an EH region that - calls terminate when an unhandled exception is throw. C++ does - this, Ada does not. */ + [ Add updated documentation on how to use this. ] */ #include "config.h" -#include "eh-common.h" #include "system.h" #include "rtl.h" #include "tree.h" #include "flags.h" -#include "except.h" #include "function.h" #include "expr.h" -#include "regs.h" -#include "hard-reg-set.h" #include "insn-config.h" -#include "recog.h" +#include "except.h" +#include "integrate.h" +#include "hard-reg-set.h" +#include "basic-block.h" #include "output.h" +#include "dwarf2asm.h" +#include "dwarf2out.h" #include "toplev.h" +#include "hashtab.h" #include "intl.h" -#include "obstack.h" #include "ggc.h" #include "tm_p.h" -/* ??? Temporary hack before this entire file is replaced. */ -#ifdef IA64_UNWIND_INFO -#define flag_new_exceptions 0 -#else -#define flag_new_exceptions 1 + +/* Provide defaults for stuff that may not be defined when using + sjlj exceptions. */ +#ifndef EH_RETURN_STACKADJ_RTX +#define EH_RETURN_STACKADJ_RTX 0 +#endif +#ifndef EH_RETURN_HANDLER_RTX +#define EH_RETURN_HANDLER_RTX 0 +#endif +#ifndef EH_RETURN_DATA_REGNO +#define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM #endif -/* One to enable asynchronous exception support. */ -int flag_non_call_exceptions = 0; +/* Nonzero means enable synchronous exceptions for non-call instructions. */ +int flag_non_call_exceptions; -/* One to protect cleanup actions with a handler that calls - __terminate, zero otherwise. */ +/* Protect cleanup actions with must-not-throw regions, with a call + to the given failure handler. */ +tree protect_cleanup_actions; -int protect_cleanup_actions_with_terminate; +/* Return true if type A catches type B. */ +int (*lang_eh_type_covers) PARAMS ((tree a, tree b)); -/* A list of labels used for exception handlers. Created by - find_exception_handler_labels for the optimization passes. */ +/* Map a type to a runtime object to match type. */ +tree (*lang_eh_runtime_type) PARAMS ((tree)); +/* A list of labels used for exception handlers. */ rtx exception_handler_labels; -/* Keeps track of the label used as the context of a throw to rethrow an - exception to the outer exception region. */ +static int call_site_base; +static int sjlj_funcdef_number; +static htab_t type_to_runtime_map; + +/* Describe the SjLj_Function_Context structure. */ +static tree sjlj_fc_type_node; +static int sjlj_fc_call_site_ofs; +static int sjlj_fc_data_ofs; +static int sjlj_fc_personality_ofs; +static int sjlj_fc_lsda_ofs; +static int sjlj_fc_jbuf_ofs; + +/* Describes one exception region. */ +struct eh_region +{ + /* The immediately surrounding region. */ + struct eh_region *outer; -struct label_node *outer_context_label_stack = NULL; + /* The list of immediately contained regions. */ + struct eh_region *inner; + struct eh_region *next_peer; -/* Pseudos used to hold exception return data in the interim between - __builtin_eh_return and the end of the function. */ + /* An identifier for this region. */ + int region_number; -static rtx eh_return_context; -static rtx eh_return_stack_adjust; -static rtx eh_return_handler; + /* Each region does exactly one thing. */ + enum eh_region_type + { + ERT_CLEANUP = 1, + ERT_TRY, + ERT_CATCH, + ERT_ALLOWED_EXCEPTIONS, + ERT_MUST_NOT_THROW, + ERT_THROW, + ERT_FIXUP + } type; + + /* Holds the action to perform based on the preceeding type. */ + union { + /* A list of catch blocks, a surrounding try block, + and the label for continuing after a catch. */ + struct { + struct eh_region *catch; + struct eh_region *last_catch; + struct eh_region *prev_try; + rtx continue_label; + } try; + + /* The list through the catch handlers, the type object + matched, and a pointer to the generated code. */ + struct { + struct eh_region *next_catch; + struct eh_region *prev_catch; + tree type; + int filter; + } catch; + + /* A tree_list of allowed types. */ + struct { + tree type_list; + int filter; + } allowed; + + /* The type given by a call to "throw foo();", or discovered + for a throw. */ + struct { + tree type; + } throw; + + /* Retain the cleanup expression even after expansion so that + we can match up fixup regions. */ + struct { + tree exp; + } cleanup; + + /* The real region (by expression and by pointer) that fixup code + should live in. */ + struct { + tree cleanup_exp; + struct eh_region *real_region; + } fixup; + } u; + + /* The region of code generated, or contained within, the region. */ + rtx label, last; + + /* Entry point for this region from the runtime eh library. */ + rtx landing_pad; + + /* Entry point for this region from an inner region. */ + rtx post_landing_pad; +}; -/* This is used for targets which can call rethrow with an offset instead - of an address. This is subtracted from the rethrow label we are - interested in. */ +/* Used to save exception status for each function. */ +struct eh_status +{ + /* The tree of all regions for this function. */ + struct eh_region *region_tree; -static rtx first_rethrow_symbol = NULL_RTX; -static rtx final_rethrow = NULL_RTX; -static rtx last_rethrow_symbol = NULL_RTX; + /* The same information as an indexable array. */ + struct eh_region **region_array; + /* The most recently open region. */ + struct eh_region *cur_region; -/* Prototypes for local functions. */ + /* This is the region for which we are processing catch blocks. */ + struct eh_region *try_region; -static void push_eh_entry PARAMS ((struct eh_stack *)); -static struct eh_entry * pop_eh_entry PARAMS ((struct eh_stack *)); -static void enqueue_eh_entry PARAMS ((struct eh_queue *, struct eh_entry *)); -static struct eh_entry * dequeue_eh_entry PARAMS ((struct eh_queue *)); -static rtx call_get_eh_context PARAMS ((void)); -static void start_dynamic_cleanup PARAMS ((tree, tree)); -static void start_dynamic_handler PARAMS ((void)); -static void expand_rethrow PARAMS ((rtx)); -static void output_exception_table_entry PARAMS ((FILE *, int)); -static rtx scan_region PARAMS ((rtx, int, int *)); -static void eh_regs PARAMS ((rtx *, rtx *, rtx *, int)); -static void set_insn_eh_region PARAMS ((rtx *, int)); -#ifdef DONT_USE_BUILTIN_SETJMP -static void jumpif_rtx PARAMS ((rtx, rtx)); -#endif -static void find_exception_handler_labels_1 PARAMS ((rtx)); -static void mark_eh_node PARAMS ((struct eh_node *)); -static void mark_eh_stack PARAMS ((struct eh_stack *)); -static void mark_eh_queue PARAMS ((struct eh_queue *)); -static void mark_tree_label_node PARAMS ((struct label_node *)); -static void mark_func_eh_entry PARAMS ((void *)); -static rtx create_rethrow_ref PARAMS ((int)); -static void push_entry PARAMS ((struct eh_stack *, struct eh_entry*)); -static void receive_exception_label PARAMS ((rtx)); -static int new_eh_region_entry PARAMS ((int, rtx)); -static int find_func_region PARAMS ((int)); -static int find_func_region_from_symbol PARAMS ((rtx)); -static void clear_function_eh_region PARAMS ((void)); -static void process_nestinfo PARAMS ((int, eh_nesting_info *, int *)); -rtx expand_builtin_return_addr PARAMS ((enum built_in_function, int, rtx)); -static void emit_cleanup_handler PARAMS ((struct eh_entry *)); -static int eh_region_from_symbol PARAMS ((rtx)); + /* A stack (TREE_LIST) of lists of handlers. The TREE_VALUE of each + node is itself a TREE_CHAINed list of handlers for regions that + are not yet closed. The TREE_VALUE of each entry contains the + handler for the corresponding entry on the ehstack. */ + tree protect_list; - -/* Various support routines to manipulate the various data structures - used by the exception handling code. */ + rtx filter; + rtx exc_ptr; -extern struct obstack permanent_obstack; + int built_landing_pads; + int last_region_number; -/* Generate a SYMBOL_REF for rethrow to use */ + varray_type ttype_data; + varray_type ehspec_data; + varray_type action_record_data; -static rtx -create_rethrow_ref (region_num) - int region_num; -{ - rtx def; - const char *ptr; - char buf[60]; + struct call_site_record + { + rtx landing_pad; + int action; + } *call_site_data; + int call_site_data_used; + int call_site_data_size; + + rtx ehr_stackadj; + rtx ehr_handler; + rtx ehr_label; + + rtx sjlj_fc; + rtx sjlj_exit_after; +}; - ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", region_num); - ptr = ggc_strdup (buf); - def = gen_rtx_SYMBOL_REF (Pmode, ptr); - SYMBOL_REF_NEED_ADJUST (def) = 1; + +static void mark_eh_region PARAMS ((struct eh_region *)); + +static int t2r_eq PARAMS ((const PTR, + const PTR)); +static hashval_t t2r_hash PARAMS ((const PTR)); +static int t2r_mark_1 PARAMS ((PTR *, PTR)); +static void t2r_mark PARAMS ((PTR)); +static void add_type_for_runtime PARAMS ((tree)); +static tree lookup_type_for_runtime PARAMS ((tree)); + +static struct eh_region *expand_eh_region_end PARAMS ((void)); + +static void collect_eh_region_array PARAMS ((void)); +static void resolve_fixup_regions PARAMS ((void)); +static void remove_fixup_regions PARAMS ((void)); +static void convert_from_eh_region_ranges_1 PARAMS ((rtx *, int *, int)); + +static struct eh_region *duplicate_eh_region_1 PARAMS ((struct eh_region *, + struct inline_remap *)); +static void duplicate_eh_region_2 PARAMS ((struct eh_region *, + struct eh_region **)); +static int ttypes_filter_eq PARAMS ((const PTR, + const PTR)); +static hashval_t ttypes_filter_hash PARAMS ((const PTR)); +static int ehspec_filter_eq PARAMS ((const PTR, + const PTR)); +static hashval_t ehspec_filter_hash PARAMS ((const PTR)); +static int add_ttypes_entry PARAMS ((htab_t, tree)); +static int add_ehspec_entry PARAMS ((htab_t, htab_t, + tree)); +static void assign_filter_values PARAMS ((void)); +static void build_post_landing_pads PARAMS ((void)); +static void connect_post_landing_pads PARAMS ((void)); +static void dw2_build_landing_pads PARAMS ((void)); + +struct sjlj_lp_info; +static bool sjlj_find_directly_reachable_regions + PARAMS ((struct sjlj_lp_info *)); +static void sjlj_assign_call_site_values + PARAMS ((rtx, struct sjlj_lp_info *)); +static void sjlj_mark_call_sites + PARAMS ((struct sjlj_lp_info *)); +static void sjlj_emit_function_enter PARAMS ((rtx)); +static void sjlj_emit_function_exit PARAMS ((void)); +static void sjlj_emit_dispatch_table + PARAMS ((rtx, struct sjlj_lp_info *)); +static void sjlj_build_landing_pads PARAMS ((void)); + +static void remove_exception_handler_label PARAMS ((rtx)); +static void remove_eh_handler PARAMS ((struct eh_region *)); + +struct reachable_info; + +/* The return value of reachable_next_level. */ +enum reachable_code +{ + /* The given exception is not processed by the given region. */ + RNL_NOT_CAUGHT, + /* The given exception may need processing by the given region. */ + RNL_MAYBE_CAUGHT, + /* The given exception is completely processed by the given region. */ + RNL_CAUGHT, + /* The given exception is completely processed by the runtime. */ + RNL_BLOCKED +}; - return def; -} +static int check_handled PARAMS ((tree, tree)); +static void add_reachable_handler + PARAMS ((struct reachable_info *, struct eh_region *, + struct eh_region *)); +static enum reachable_code reachable_next_level + PARAMS ((struct eh_region *, tree, struct reachable_info *)); + +static int action_record_eq PARAMS ((const PTR, + const PTR)); +static hashval_t action_record_hash PARAMS ((const PTR)); +static int add_action_record PARAMS ((htab_t, int, int)); +static int collect_one_action_chain PARAMS ((htab_t, + struct eh_region *)); +static int add_call_site PARAMS ((rtx, int)); + +static void push_uleb128 PARAMS ((varray_type *, + unsigned int)); +static void push_sleb128 PARAMS ((varray_type *, int)); +static const char *eh_data_format_name PARAMS ((int)); +#ifndef HAVE_AS_LEB128 +static int dw2_size_of_call_site_table PARAMS ((void)); +static int sjlj_size_of_call_site_table PARAMS ((void)); +#endif +static void dw2_output_call_site_table PARAMS ((void)); +static void sjlj_output_call_site_table PARAMS ((void)); -/* Push a label entry onto the given STACK. */ + +/* Routine to see if exception handling is turned on. + DO_WARN is non-zero if we want to inform the user that exception + handling is turned off. -void -push_label_entry (stack, rlabel, tlabel) - struct label_node **stack; - rtx rlabel; - tree tlabel; -{ - struct label_node *newnode - = (struct label_node *) xmalloc (sizeof (struct label_node)); + This is used to ensure that -fexceptions has been specified if the + compiler tries to use any exception-specific functions. */ - if (rlabel) - newnode->u.rlabel = rlabel; - else - newnode->u.tlabel = tlabel; - newnode->chain = *stack; - *stack = newnode; +int +doing_eh (do_warn) + int do_warn; +{ + if (! flag_exceptions) + { + static int warned = 0; + if (! warned && do_warn) + { + error ("exception handling disabled, use -fexceptions to enable"); + warned = 1; + } + return 0; + } + return 1; } -/* Pop a label entry from the given STACK. */ - -rtx -pop_label_entry (stack) - struct label_node **stack; + +void +init_eh () { - rtx label; - struct label_node *tempnode; - - if (! *stack) - return NULL_RTX; - - tempnode = *stack; - label = tempnode->u.rlabel; - *stack = (*stack)->chain; - free (tempnode); - - return label; -} + ggc_add_rtx_root (&exception_handler_labels, 1); + ggc_add_tree_root (&protect_cleanup_actions, 1); -/* Return the top element of the given STACK. */ + if (! flag_exceptions) + return; -tree -top_label_entry (stack) - struct label_node **stack; -{ - if (! *stack) - return NULL_TREE; + type_to_runtime_map = htab_create (31, t2r_hash, t2r_eq, NULL); + ggc_add_root (&type_to_runtime_map, 1, sizeof (htab_t), t2r_mark); - return (*stack)->u.tlabel; -} + /* Create the SjLj_Function_Context structure. This should match + the definition in unwind-sjlj.c. */ + if (USING_SJLJ_EXCEPTIONS) + { + tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp; -/* Get an exception label. */ + sjlj_fc_type_node = make_lang_type (RECORD_TYPE); + ggc_add_tree_root (&sjlj_fc_type_node, 1); -rtx -gen_exception_label () -{ - rtx lab; - lab = gen_label_rtx (); - return lab; -} + f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"), + build_pointer_type (sjlj_fc_type_node)); + DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node; -/* Push a new eh_node entry onto STACK. */ + f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"), + integer_type_node); + DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node; -static void -push_eh_entry (stack) - struct eh_stack *stack; -{ - struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node)); - struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry)); - - rtx rlab = gen_exception_label (); - entry->finalization = NULL_TREE; - entry->label_used = 0; - entry->exception_handler_label = rlab; - entry->false_label = NULL_RTX; - if (! flag_new_exceptions) - entry->outer_context = gen_label_rtx (); - else - entry->outer_context = create_rethrow_ref (CODE_LABEL_NUMBER (rlab)); - entry->rethrow_label = entry->outer_context; - entry->goto_entry_p = 0; + tmp = build_index_type (build_int_2 (4 - 1, 0)); + tmp = build_array_type (type_for_mode (word_mode, 1), tmp); + f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp); + DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node; - node->entry = entry; - node->chain = stack->top; - stack->top = node; -} + f_per = build_decl (FIELD_DECL, get_identifier ("__personality"), + ptr_type_node); + DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node; -/* Push an existing entry onto a stack. */ + f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"), + ptr_type_node); + DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node; -static void -push_entry (stack, entry) - struct eh_stack *stack; - struct eh_entry *entry; -{ - struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node)); - node->entry = entry; - node->chain = stack->top; - stack->top = node; +#ifdef DONT_USE_BUILTIN_SETJMP +#ifdef JMP_BUF_SIZE + tmp = build_int_2 (JMP_BUF_SIZE - 1, 0); +#else + /* Should be large enough for most systems, if it is not, + JMP_BUF_SIZE should be defined with the proper value. It will + also tend to be larger than necessary for most systems, a more + optimal port will define JMP_BUF_SIZE. */ + tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0); +#endif +#else + /* This is 2 for builtin_setjmp, plus whatever the target requires + via STACK_SAVEAREA_MODE (SAVE_NONLOCAL). */ + tmp = build_int_2 ((GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL)) + / GET_MODE_SIZE (Pmode)) + 2 - 1, 0); +#endif + tmp = build_index_type (tmp); + tmp = build_array_type (ptr_type_node, tmp); + f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp); +#ifdef DONT_USE_BUILTIN_SETJMP + /* We don't know what the alignment requirements of the + runtime's jmp_buf has. Overestimate. */ + DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT; + DECL_USER_ALIGN (f_jbuf) = 1; +#endif + DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node; + + TYPE_FIELDS (sjlj_fc_type_node) = f_prev; + TREE_CHAIN (f_prev) = f_cs; + TREE_CHAIN (f_cs) = f_data; + TREE_CHAIN (f_data) = f_per; + TREE_CHAIN (f_per) = f_lsda; + TREE_CHAIN (f_lsda) = f_jbuf; + + layout_type (sjlj_fc_type_node); + + /* Cache the interesting field offsets so that we have + easy access from rtl. */ + sjlj_fc_call_site_ofs + = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1) + + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT); + sjlj_fc_data_ofs + = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1) + + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT); + sjlj_fc_personality_ofs + = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1) + + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT); + sjlj_fc_lsda_ofs + = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1) + + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT); + sjlj_fc_jbuf_ofs + = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1) + + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT); + } } -/* Pop an entry from the given STACK. */ - -static struct eh_entry * -pop_eh_entry (stack) - struct eh_stack *stack; +void +init_eh_for_function () { - struct eh_node *tempnode; - struct eh_entry *tempentry; - - tempnode = stack->top; - tempentry = tempnode->entry; - stack->top = stack->top->chain; - free (tempnode); - - return tempentry; + cfun->eh = (struct eh_status *) xcalloc (1, sizeof (struct eh_status)); } -/* Enqueue an ENTRY onto the given QUEUE. */ +/* Mark EH for GC. */ static void -enqueue_eh_entry (queue, entry) - struct eh_queue *queue; - struct eh_entry *entry; +mark_eh_region (region) + struct eh_region *region; { - struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node)); + if (! region) + return; - node->entry = entry; - node->chain = NULL; + switch (region->type) + { + case ERT_CLEANUP: + ggc_mark_tree (region->u.cleanup.exp); + break; + case ERT_TRY: + ggc_mark_rtx (region->u.try.continue_label); + break; + case ERT_CATCH: + ggc_mark_tree (region->u.catch.type); + break; + case ERT_ALLOWED_EXCEPTIONS: + ggc_mark_tree (region->u.allowed.type_list); + break; + case ERT_MUST_NOT_THROW: + break; + case ERT_THROW: + ggc_mark_tree (region->u.throw.type); + break; + case ERT_FIXUP: + ggc_mark_tree (region->u.fixup.cleanup_exp); + break; + default: + abort (); + } - if (queue->head == NULL) - queue->head = node; - else - queue->tail->chain = node; - queue->tail = node; + ggc_mark_rtx (region->label); + ggc_mark_rtx (region->last); + ggc_mark_rtx (region->landing_pad); + ggc_mark_rtx (region->post_landing_pad); } -/* Dequeue an entry from the given QUEUE. */ - -static struct eh_entry * -dequeue_eh_entry (queue) - struct eh_queue *queue; +void +mark_eh_status (eh) + struct eh_status *eh; { - struct eh_node *tempnode; - struct eh_entry *tempentry; + int i; + + if (eh == 0) + return; + + /* If we've called collect_eh_region_array, use it. Otherwise walk + the tree non-recursively. */ + if (eh->region_array) + { + for (i = eh->last_region_number; i > 0; --i) + { + struct eh_region *r = eh->region_array[i]; + if (r && r->region_number == i) + mark_eh_region (r); + } + } + else if (eh->region_tree) + { + struct eh_region *r = eh->region_tree; + while (1) + { + mark_eh_region (r); + if (r->inner) + r = r->inner; + else if (r->next_peer) + r = r->next_peer; + else + { + do { + r = r->outer; + if (r == NULL) + goto tree_done; + } while (r->next_peer == NULL); + r = r->next_peer; + } + } + tree_done:; + } - if (queue->head == NULL) - return NULL; + ggc_mark_tree (eh->protect_list); + ggc_mark_rtx (eh->filter); + ggc_mark_rtx (eh->exc_ptr); + ggc_mark_tree_varray (eh->ttype_data); - tempnode = queue->head; - queue->head = queue->head->chain; + if (eh->call_site_data) + { + for (i = eh->call_site_data_used - 1; i >= 0; --i) + ggc_mark_rtx (eh->call_site_data[i].landing_pad); + } - tempentry = tempnode->entry; - free (tempnode); + ggc_mark_rtx (eh->ehr_stackadj); + ggc_mark_rtx (eh->ehr_handler); + ggc_mark_rtx (eh->ehr_label); - return tempentry; + ggc_mark_rtx (eh->sjlj_fc); + ggc_mark_rtx (eh->sjlj_exit_after); } -static void -receive_exception_label (handler_label) - rtx handler_label; +void +free_eh_status (f) + struct function *f; { - rtx around_label = NULL_RTX; + struct eh_status *eh = f->eh; - if (! flag_new_exceptions || USING_SJLJ_EXCEPTIONS) - { - around_label = gen_label_rtx (); - emit_jump (around_label); - emit_barrier (); - } - - emit_label (handler_label); - - if (! USING_SJLJ_EXCEPTIONS) + if (eh->region_array) { -#ifdef HAVE_exception_receiver - if (HAVE_exception_receiver) - emit_insn (gen_exception_receiver ()); - else -#endif -#ifdef HAVE_nonlocal_goto_receiver - if (HAVE_nonlocal_goto_receiver) - emit_insn (gen_nonlocal_goto_receiver ()); - else -#endif - { /* Nothing */ } + int i; + for (i = eh->last_region_number; i > 0; --i) + { + struct eh_region *r = eh->region_array[i]; + /* Mind we don't free a region struct more than once. */ + if (r && r->region_number == i) + free (r); + } + free (eh->region_array); } - else + else if (eh->region_tree) { -#ifndef DONT_USE_BUILTIN_SETJMP - expand_builtin_setjmp_receiver (handler_label); -#endif + struct eh_region *next, *r = eh->region_tree; + while (1) + { + if (r->inner) + r = r->inner; + else if (r->next_peer) + { + next = r->next_peer; + free (r); + r = next; + } + else + { + do { + next = r->outer; + free (r); + r = next; + if (r == NULL) + goto tree_done; + } while (r->next_peer == NULL); + next = r->next_peer; + free (r); + r = next; + } + } + tree_done:; } - if (around_label) - emit_label (around_label); + VARRAY_FREE (eh->ttype_data); + VARRAY_FREE (eh->ehspec_data); + VARRAY_FREE (eh->action_record_data); + if (eh->call_site_data) + free (eh->call_site_data); + + free (eh); + f->eh = NULL; } + +/* Start an exception handling region. All instructions emitted + after this point are considered to be part of the region until + expand_eh_region_end is invoked. */ -struct func_eh_entry +void +expand_eh_region_start () { - int range_number; /* EH region number from EH NOTE insn's. */ - rtx rethrow_label; /* Label for rethrow. */ - int rethrow_ref; /* Is rethrow_label referenced? */ - int emitted; /* 1 if this entry has been emitted in assembly file. */ - struct handler_info *handlers; -}; + struct eh_region *new_region; + struct eh_region *cur_region; + rtx note; + if (! doing_eh (0)) + return; -/* table of function eh regions */ -static struct func_eh_entry *function_eh_regions = NULL; -static int num_func_eh_entries = 0; -static int current_func_eh_entry = 0; + /* We need a new block to record the start and end of the dynamic + handler chain. We also want to prevent jumping into a try block. */ + expand_start_bindings (2); -#define SIZE_FUNC_EH(X) (sizeof (struct func_eh_entry) * X) + /* But we don't need or want a new temporary level. */ + pop_temp_slots (); -/* Add a new eh_entry for this function. The number returned is an - number which uniquely identifies this exception range. */ + /* Mark this block as created by expand_eh_region_start. This is so + that we can pop the block with expand_end_bindings automatically. */ + mark_block_as_eh_region (); -static int -new_eh_region_entry (note_eh_region, rethrow) - int note_eh_region; - rtx rethrow; -{ - if (current_func_eh_entry == num_func_eh_entries) + /* Insert a new blank region as a leaf in the tree. */ + new_region = (struct eh_region *) xcalloc (1, sizeof (*new_region)); + cur_region = cfun->eh->cur_region; + new_region->outer = cur_region; + if (cur_region) { - if (num_func_eh_entries == 0) - { - function_eh_regions = - (struct func_eh_entry *) xmalloc (SIZE_FUNC_EH (50)); - num_func_eh_entries = 50; - } - else - { - num_func_eh_entries = num_func_eh_entries * 3 / 2; - function_eh_regions = (struct func_eh_entry *) - xrealloc (function_eh_regions, SIZE_FUNC_EH (num_func_eh_entries)); - } - } - function_eh_regions[current_func_eh_entry].range_number = note_eh_region; - if (rethrow == NULL_RTX) - function_eh_regions[current_func_eh_entry].rethrow_label = - create_rethrow_ref (note_eh_region); + new_region->next_peer = cur_region->inner; + cur_region->inner = new_region; + } else - function_eh_regions[current_func_eh_entry].rethrow_label = rethrow; - function_eh_regions[current_func_eh_entry].handlers = NULL; - function_eh_regions[current_func_eh_entry].emitted = 0; - - return current_func_eh_entry++; -} - -/* Add new handler information to an exception range. The first parameter - specifies the range number (returned from new_eh_entry()). The second - parameter specifies the handler. By default the handler is inserted at - the end of the list. A handler list may contain only ONE NULL_TREE - typeinfo entry. Regardless where it is positioned, a NULL_TREE entry - is always output as the LAST handler in the exception table for a region. */ - -void -add_new_handler (region, newhandler) - int region; - struct handler_info *newhandler; -{ - struct handler_info *last; - - /* If find_func_region returns -1, callers might attempt to pass us - this region number. If that happens, something has gone wrong; - -1 is never a valid region. */ - if (region == -1) - abort (); - - newhandler->next = NULL; - last = function_eh_regions[region].handlers; - if (last == NULL) - function_eh_regions[region].handlers = newhandler; - else { - for ( ; ; last = last->next) - { - if (last->type_info == CATCH_ALL_TYPE) - pedwarn ("additional handler after ..."); - if (last->next == NULL) - break; - } - last->next = newhandler; + new_region->next_peer = cfun->eh->region_tree; + cfun->eh->region_tree = new_region; } + cfun->eh->cur_region = new_region; + + /* Create a note marking the start of this region. */ + new_region->region_number = ++cfun->eh->last_region_number; + note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG); + NOTE_EH_HANDLER (note) = new_region->region_number; } -/* Remove a handler label. The handler label is being deleted, so all - regions which reference this handler should have it removed from their - list of possible handlers. Any region which has the final handler - removed can be deleted. */ +/* Common code to end a region. Returns the region just ended. */ -void remove_handler (removing_label) - rtx removing_label; +static struct eh_region * +expand_eh_region_end () { - struct handler_info *handler, *last; - int x; - for (x = 0 ; x < current_func_eh_entry; ++x) + struct eh_region *cur_region = cfun->eh->cur_region; + rtx note; + + /* Create a nute marking the end of this region. */ + note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END); + NOTE_EH_HANDLER (note) = cur_region->region_number; + + /* Pop. */ + cfun->eh->cur_region = cur_region->outer; + + /* If we have already started ending the bindings, don't recurse. */ + if (is_eh_region ()) { - last = NULL; - handler = function_eh_regions[x].handlers; - for ( ; handler; last = handler, handler = handler->next) - if (handler->handler_label == removing_label) - { - if (last) - { - last->next = handler->next; - handler = last; - } - else - function_eh_regions[x].handlers = handler->next; - } + /* Because we don't need or want a new temporary level and + because we didn't create one in expand_eh_region_start, + create a fake one now to avoid removing one in + expand_end_bindings. */ + push_temp_slots (); + + mark_block_as_not_eh_region (); + + expand_end_bindings (NULL_TREE, 0, 0); } + + return cur_region; } -/* This function will return a malloc'd pointer to an array of - void pointer representing the runtime match values that - currently exist in all regions. */ +/* End an exception handling region for a cleanup. HANDLER is an + expression to expand for the cleanup. */ -int -find_all_handler_type_matches (array) - void ***array; +void +expand_eh_region_end_cleanup (handler) + tree handler; { - struct handler_info *handler, *last; - int x,y; - void *val; - void **ptr; - int max_ptr; - int n_ptr = 0; + struct eh_region *region; + rtx around_label; + + if (! doing_eh (0)) + return; - *array = NULL; + region = expand_eh_region_end (); + region->type = ERT_CLEANUP; + region->label = gen_label_rtx (); + region->u.cleanup.exp = handler; - if (!doing_eh (0) || ! flag_new_exceptions) - return 0; + around_label = gen_label_rtx (); + emit_jump (around_label); - max_ptr = 100; - ptr = (void **) xmalloc (max_ptr * sizeof (void *)); + emit_label (region->label); - for (x = 0 ; x < current_func_eh_entry; x++) - { - last = NULL; - handler = function_eh_regions[x].handlers; - for ( ; handler; last = handler, handler = handler->next) - { - val = handler->type_info; - if (val != NULL && val != CATCH_ALL_TYPE) - { - /* See if this match value has already been found. */ - for (y = 0; y < n_ptr; y++) - if (ptr[y] == val) - break; + if (protect_cleanup_actions) + expand_eh_region_start (); - /* If we break early, we already found this value. */ - if (y < n_ptr) - continue; + expand_expr (handler, const0_rtx, VOIDmode, 0); - /* Do we need to allocate more space? */ - if (n_ptr >= max_ptr) - { - max_ptr += max_ptr / 2; - ptr = (void **) xrealloc (ptr, max_ptr * sizeof (void *)); - } - ptr[n_ptr] = val; - n_ptr++; - } - } - } + if (protect_cleanup_actions) + expand_eh_region_end_must_not_throw (protect_cleanup_actions); - if (n_ptr == 0) - { - free (ptr); - ptr = NULL; - } - *array = ptr; - return n_ptr; + /* We delay the generation of the _Unwind_Resume until we generate + landing pads. We emit a marker here so as to get good control + flow data in the meantime. */ + emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number)); + emit_barrier (); + + region->last = get_last_insn (); + + emit_label (around_label); } -/* Create a new handler structure initialized with the handler label and - typeinfo fields passed in. */ +/* End an exception handling region for a try block, and prepares + for subsequent calls to expand_start_catch. */ -struct handler_info * -get_new_handler (handler, typeinfo) - rtx handler; - void *typeinfo; +void +expand_start_all_catch () { - struct handler_info* ptr; - ptr = (struct handler_info *) xmalloc (sizeof (struct handler_info)); - ptr->handler_label = handler; - ptr->handler_number = CODE_LABEL_NUMBER (handler); - ptr->type_info = typeinfo; - ptr->next = NULL; + struct eh_region *region; - return ptr; -} + if (! doing_eh (1)) + return; + region = expand_eh_region_end (); + region->type = ERT_TRY; + region->u.try.prev_try = cfun->eh->try_region; + region->u.try.continue_label = gen_label_rtx (); + cfun->eh->try_region = region; + + emit_jump (region->u.try.continue_label); +} -/* Find the index in function_eh_regions associated with a NOTE region. If - the region cannot be found, a -1 is returned. */ +/* Begin a catch clause. TYPE is the type caught, or null if this is + a catch-all clause. */ -static int -find_func_region (insn_region) - int insn_region; +void +expand_start_catch (type) + tree type; { - int x; - for (x = 0; x < current_func_eh_entry; x++) - if (function_eh_regions[x].range_number == insn_region) - return x; + struct eh_region *t, *c, *l; + + if (! doing_eh (0)) + return; + + if (type) + add_type_for_runtime (type); + expand_eh_region_start (); + + t = cfun->eh->try_region; + c = cfun->eh->cur_region; + c->type = ERT_CATCH; + c->u.catch.type = type; + c->label = gen_label_rtx (); + + l = t->u.try.last_catch; + c->u.catch.prev_catch = l; + if (l) + l->u.catch.next_catch = c; + else + t->u.try.catch = c; + t->u.try.last_catch = c; - return -1; + emit_label (c->label); } -/* Get a pointer to the first handler in an exception region's list. */ +/* End a catch clause. Control will resume after the try/catch block. */ -struct handler_info * -get_first_handler (region) - int region; +void +expand_end_catch () { - int r = find_func_region (region); - if (r == -1) - abort (); - return function_eh_regions[r].handlers; + struct eh_region *try_region, *catch_region; + + if (! doing_eh (0)) + return; + + catch_region = expand_eh_region_end (); + try_region = cfun->eh->try_region; + + emit_jump (try_region->u.try.continue_label); + + catch_region->last = get_last_insn (); } -/* Clean out the function_eh_region table and free all memory */ +/* End a sequence of catch handlers for a try block. */ -static void -clear_function_eh_region () +void +expand_end_all_catch () { - int x; - struct handler_info *ptr, *next; - for (x = 0; x < current_func_eh_entry; x++) - for (ptr = function_eh_regions[x].handlers; ptr != NULL; ptr = next) - { - next = ptr->next; - free (ptr); - } - if (function_eh_regions) - free (function_eh_regions); - num_func_eh_entries = 0; - current_func_eh_entry = 0; + struct eh_region *try_region; + + if (! doing_eh (0)) + return; + + try_region = cfun->eh->try_region; + cfun->eh->try_region = try_region->u.try.prev_try; + + emit_label (try_region->u.try.continue_label); } -/* Make a duplicate of an exception region by copying all the handlers - for an exception region. Return the new handler index. The final - parameter is a routine which maps old labels to new ones. */ +/* End an exception region for an exception type filter. ALLOWED is a + TREE_LIST of types to be matched by the runtime. FAILURE is an + expression to invoke if a mismatch ocurrs. */ -int -duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map) - int old_note_eh_region, new_note_eh_region; - rtx (*map) PARAMS ((rtx)); +void +expand_eh_region_end_allowed (allowed, failure) + tree allowed, failure; { - struct handler_info *ptr, *new_ptr; - int new_region, region; + struct eh_region *region; + rtx around_label; - region = find_func_region (old_note_eh_region); - if (region == -1) - /* Cannot duplicate non-existant exception region. */ - abort (); + if (! doing_eh (0)) + return; - /* duplicate_eh_handlers may have been called during a symbol remap. */ - new_region = find_func_region (new_note_eh_region); - if (new_region != -1) - return (new_region); + region = expand_eh_region_end (); + region->type = ERT_ALLOWED_EXCEPTIONS; + region->u.allowed.type_list = allowed; + region->label = gen_label_rtx (); - new_region = new_eh_region_entry (new_note_eh_region, NULL_RTX); + for (; allowed ; allowed = TREE_CHAIN (allowed)) + add_type_for_runtime (TREE_VALUE (allowed)); - ptr = function_eh_regions[region].handlers; + /* We must emit the call to FAILURE here, so that if this function + throws a different exception, that it will be processed by the + correct region. */ - for ( ; ptr; ptr = ptr->next) - { - new_ptr = get_new_handler (map (ptr->handler_label), ptr->type_info); - add_new_handler (new_region, new_ptr); - } + around_label = gen_label_rtx (); + emit_jump (around_label); + + emit_label (region->label); + expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL); - return new_region; + region->last = get_last_insn (); + + emit_label (around_label); } +/* End an exception region for a must-not-throw filter. FAILURE is an + expression invoke if an uncaught exception propagates this far. -/* Given a rethrow symbol, find the EH region number this is for. */ + This is conceptually identical to expand_eh_region_end_allowed with + an empty allowed list (if you passed "std::terminate" instead of + "__cxa_call_unexpected"), but they are represented differently in + the C++ LSDA. */ -static int -eh_region_from_symbol (sym) - rtx sym; +void +expand_eh_region_end_must_not_throw (failure) + tree failure; { - int x; - if (sym == last_rethrow_symbol) - return 1; - for (x = 0; x < current_func_eh_entry; x++) - if (function_eh_regions[x].rethrow_label == sym) - return function_eh_regions[x].range_number; - return -1; -} + struct eh_region *region; + rtx around_label; -/* Like find_func_region, but using the rethrow symbol for the region - rather than the region number itself. */ + if (! doing_eh (0)) + return; -static int -find_func_region_from_symbol (sym) - rtx sym; -{ - return find_func_region (eh_region_from_symbol (sym)); -} + region = expand_eh_region_end (); + region->type = ERT_MUST_NOT_THROW; + region->label = gen_label_rtx (); -/* When inlining/unrolling, we have to map the symbols passed to - __rethrow as well. This performs the remap. If a symbol isn't foiund, - the original one is returned. This is not an efficient routine, - so don't call it on everything!! */ + /* We must emit the call to FAILURE here, so that if this function + throws a different exception, that it will be processed by the + correct region. */ -rtx -rethrow_symbol_map (sym, map) - rtx sym; - rtx (*map) PARAMS ((rtx)); -{ - int x, y; + around_label = gen_label_rtx (); + emit_jump (around_label); - if (! flag_new_exceptions) - return sym; + emit_label (region->label); + expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL); - for (x = 0; x < current_func_eh_entry; x++) - if (function_eh_regions[x].rethrow_label == sym) - { - /* We've found the original region, now lets determine which region - this now maps to. */ - rtx l1 = function_eh_regions[x].handlers->handler_label; - rtx l2 = map (l1); - y = CODE_LABEL_NUMBER (l2); /* This is the new region number */ - x = find_func_region (y); /* Get the new permanent region */ - if (x == -1) /* Hmm, Doesn't exist yet */ - { - x = duplicate_eh_handlers (CODE_LABEL_NUMBER (l1), y, map); - /* Since we're mapping it, it must be used. */ - function_eh_regions[x].rethrow_ref = 1; - } - return function_eh_regions[x].rethrow_label; - } - return sym; + region->last = get_last_insn (); + + emit_label (around_label); } -/* Returns nonzero if the rethrow label for REGION is referenced - somewhere (i.e. we rethrow out of REGION or some other region - masquerading as REGION). */ +/* End an exception region for a throw. No handling goes on here, + but it's the easiest way for the front-end to indicate what type + is being thrown. */ -int -rethrow_used (region) - int region; +void +expand_eh_region_end_throw (type) + tree type; { - if (flag_new_exceptions) - { - int ret = function_eh_regions[find_func_region (region)].rethrow_ref; - return ret; - } - return 0; + struct eh_region *region; + + if (! doing_eh (0)) + return; + + region = expand_eh_region_end (); + region->type = ERT_THROW; + region->u.throw.type = type; } - -/* Routine to see if exception handling is turned on. - DO_WARN is non-zero if we want to inform the user that exception - handling is turned off. +/* End a fixup region. Within this region the cleanups for the immediately + enclosing region are _not_ run. This is used for goto cleanup to avoid + destroying an object twice. - This is used to ensure that -fexceptions has been specified if the - compiler tries to use any exception-specific functions. */ + This would be an extraordinarily simple prospect, were it not for the + fact that we don't actually know what the immediately enclosing region + is. This surprising fact is because expand_cleanups is currently + generating a sequence that it will insert somewhere else. We collect + the proper notion of "enclosing" in convert_from_eh_region_ranges. */ -int -doing_eh (do_warn) - int do_warn; +void +expand_eh_region_end_fixup (handler) + tree handler; { - if (! flag_exceptions) - { - static int warned = 0; - if (! warned && do_warn) - { - error ("exception handling disabled, use -fexceptions to enable"); - warned = 1; - } - return 0; - } - return 1; + struct eh_region *fixup; + + if (! doing_eh (0)) + return; + + fixup = expand_eh_region_end (); + fixup->type = ERT_FIXUP; + fixup->u.fixup.cleanup_exp = handler; } -/* Given a return address in ADDR, determine the address we should use - to find the corresponding EH region. */ +/* Return a tree expression for a pointer to the exception object + within a handler. */ rtx -eh_outer_context (addr) - rtx addr; +get_exception_pointer () { - /* First mask out any unwanted bits. */ -#ifdef MASK_RETURN_ADDR - expand_and (addr, MASK_RETURN_ADDR, addr); -#endif + rtx exc_ptr = cfun->eh->exc_ptr; + if (! exc_ptr) + { + exc_ptr = gen_reg_rtx (Pmode); + cfun->eh->exc_ptr = exc_ptr; + } + return exc_ptr; +} - /* Then adjust to find the real return address. */ -#if defined (RETURN_ADDR_OFFSET) - addr = plus_constant (addr, RETURN_ADDR_OFFSET); -#endif + +/* Begin a region that will contain entries created with + add_partial_entry. */ - return addr; +void +begin_protect_partials () +{ + /* Push room for a new list. */ + cfun->eh->protect_list + = tree_cons (NULL_TREE, NULL_TREE, cfun->eh->protect_list); } /* Start a new exception region for a region of code that has a @@ -1121,1819 +986,1886 @@ add_partial_entry (handler) { expand_eh_region_start (); - /* Because this is a cleanup action, we may have to protect the handler - with __terminate. */ - handler = protect_with_terminate (handler); - + /* ??? This comment was old before the most recent rewrite. We + really ought to fix the callers at some point. */ /* For backwards compatibility, we allow callers to omit calls to begin_protect_partials for the outermost region. So, we must explicitly do so here. */ - if (!protect_list) + if (!cfun->eh->protect_list) begin_protect_partials (); /* Add this entry to the front of the list. */ - TREE_VALUE (protect_list) - = tree_cons (NULL_TREE, handler, TREE_VALUE (protect_list)); + TREE_VALUE (cfun->eh->protect_list) + = tree_cons (NULL_TREE, handler, TREE_VALUE (cfun->eh->protect_list)); } -/* Emit code to get EH context to current function. */ +/* End all the pending exception regions on protect_list. */ -static rtx -call_get_eh_context () +void +end_protect_partials () { - static tree fn; - tree expr; - - if (fn == NULL_TREE) - { - tree fntype; - fn = get_identifier ("__get_eh_context"); - fntype = build_pointer_type (build_pointer_type - (build_pointer_type (void_type_node))); - fntype = build_function_type (fntype, NULL_TREE); - fn = build_decl (FUNCTION_DECL, fn, fntype); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - TREE_READONLY (fn) = 1; - make_decl_rtl (fn, NULL_PTR); - assemble_external (fn); + tree t; - ggc_add_tree_root (&fn, 1); - } + /* ??? This comment was old before the most recent rewrite. We + really ought to fix the callers at some point. */ + /* For backwards compatibility, we allow callers to omit the call to + begin_protect_partials for the outermost region. So, + PROTECT_LIST may be NULL. */ + if (!cfun->eh->protect_list) + return; - expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); - expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), - expr, NULL_TREE, NULL_TREE); - TREE_SIDE_EFFECTS (expr) = 1; + /* Pop the topmost entry. */ + t = TREE_VALUE (cfun->eh->protect_list); + cfun->eh->protect_list = TREE_CHAIN (cfun->eh->protect_list); - return copy_to_reg (expand_expr (expr, NULL_RTX, VOIDmode, 0)); + /* End all the exception regions. */ + for (; t; t = TREE_CHAIN (t)) + expand_eh_region_end_cleanup (TREE_VALUE (t)); } -/* Get a reference to the EH context. - We will only generate a register for the current function EH context here, - and emit a USE insn to mark that this is a EH context register. - - Later, emit_eh_context will emit needed call to __get_eh_context - in libgcc2, and copy the value to the register we have generated. */ - -rtx -get_eh_context () -{ - if (current_function_ehc == 0) - { - rtx insn; + +/* This section is for the exception handling specific optimization pass. */ - current_function_ehc = gen_reg_rtx (Pmode); - - insn = gen_rtx_USE (GET_MODE (current_function_ehc), - current_function_ehc); - insn = emit_insn_before (insn, get_first_nonparm_insn ()); - - REG_NOTES (insn) - = gen_rtx_EXPR_LIST (REG_EH_CONTEXT, current_function_ehc, - REG_NOTES (insn)); - } - return current_function_ehc; -} - -/* Get a reference to the dynamic handler chain. It points to the - pointer to the next element in the dynamic handler chain. It ends - when there are no more elements in the dynamic handler chain, when - the value is &top_elt from libgcc2.c. Immediately after the - pointer, is an area suitable for setjmp/longjmp when - DONT_USE_BUILTIN_SETJMP is defined, and an area suitable for - __builtin_setjmp/__builtin_longjmp when DONT_USE_BUILTIN_SETJMP - isn't defined. */ +/* Random access the exception region tree. It's just as simple to + collect the regions this way as in expand_eh_region_start, but + without having to realloc memory. */ -rtx -get_dynamic_handler_chain () +static void +collect_eh_region_array () { - rtx ehc, dhc, result; + struct eh_region **array, *i; - ehc = get_eh_context (); - - /* This is the offset of dynamic_handler_chain in the eh_context struct - declared in eh-common.h. If its location is change, change this offset */ - dhc = plus_constant (ehc, POINTER_SIZE / BITS_PER_UNIT); + i = cfun->eh->region_tree; + if (! i) + return; - result = copy_to_reg (dhc); + array = xcalloc (cfun->eh->last_region_number + 1, sizeof (*array)); + cfun->eh->region_array = array; - /* We don't want a copy of the dcc, but rather, the single dcc. */ - return gen_rtx_MEM (Pmode, result); + while (1) + { + array[i->region_number] = i; + + /* If there are sub-regions, process them. */ + if (i->inner) + i = i->inner; + /* If there are peers, process them. */ + else if (i->next_peer) + i = i->next_peer; + /* Otherwise, step back up the tree to the next peer. */ + else + { + do { + i = i->outer; + if (i == NULL) + return; + } while (i->next_peer == NULL); + i = i->next_peer; + } + } } -/* Get a reference to the dynamic cleanup chain. It points to the - pointer to the next element in the dynamic cleanup chain. - Immediately after the pointer, are two Pmode variables, one for a - pointer to a function that performs the cleanup action, and the - second, the argument to pass to that function. */ - -rtx -get_dynamic_cleanup_chain () +static void +resolve_fixup_regions () { - rtx dhc, dcc, result; + int i, j, n = cfun->eh->last_region_number; - dhc = get_dynamic_handler_chain (); - dcc = plus_constant (dhc, POINTER_SIZE / BITS_PER_UNIT); + for (i = 1; i <= n; ++i) + { + struct eh_region *fixup = cfun->eh->region_array[i]; + struct eh_region *cleanup; - result = copy_to_reg (dcc); + if (! fixup || fixup->type != ERT_FIXUP) + continue; - /* We don't want a copy of the dcc, but rather, the single dcc. */ - return gen_rtx_MEM (Pmode, result); -} - -#ifdef DONT_USE_BUILTIN_SETJMP -/* Generate code to evaluate X and jump to LABEL if the value is nonzero. - LABEL is an rtx of code CODE_LABEL, in this function. */ + for (j = 1; j <= n; ++j) + { + cleanup = cfun->eh->region_array[j]; + if (cleanup->type == ERT_CLEANUP + && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp) + break; + } + if (j > n) + abort (); -static void -jumpif_rtx (x, label) - rtx x; - rtx label; -{ - jumpif (make_tree (type_for_mode (GET_MODE (x), 0), x), label); + fixup->u.fixup.real_region = cleanup->outer; + } } -#endif -/* Start a dynamic cleanup on the EH runtime dynamic cleanup stack. - We just need to create an element for the cleanup list, and push it - into the chain. - - A dynamic cleanup is a cleanup action implied by the presence of an - element on the EH runtime dynamic cleanup stack that is to be - performed when an exception is thrown. The cleanup action is - performed by __sjthrow when an exception is thrown. Only certain - actions can be optimized into dynamic cleanup actions. For the - restrictions on what actions can be performed using this routine, - see expand_eh_region_start_tree. */ +/* Now that we've discovered what region actually encloses a fixup, + we can shuffle pointers and remove them from the tree. */ static void -start_dynamic_cleanup (func, arg) - tree func; - tree arg; +remove_fixup_regions () { - rtx dcc; - rtx new_func, new_arg; - rtx x, buf; - int size; - - /* We allocate enough room for a pointer to the function, and - one argument. */ - size = 2; + int i; - /* XXX, FIXME: The stack space allocated this way is too long lived, - but there is no allocation routine that allocates at the level of - the last binding contour. */ - buf = assign_stack_local (BLKmode, - GET_MODE_SIZE (Pmode)*(size+1), - 0); + for (i = cfun->eh->last_region_number; i > 0; --i) + { + struct eh_region *fixup = cfun->eh->region_array[i]; - buf = change_address (buf, Pmode, NULL_RTX); + if (! fixup) + continue; - /* Store dcc into the first word of the newly allocated buffer. */ + /* Allow GC to maybe free some memory. */ + if (fixup->type == ERT_CLEANUP) + fixup->u.cleanup.exp = NULL_TREE; - dcc = get_dynamic_cleanup_chain (); - emit_move_insn (buf, dcc); + if (fixup->type != ERT_FIXUP) + continue; - /* Store func and arg into the cleanup list element. */ + if (fixup->inner) + { + struct eh_region *parent, *p, **pp; - new_func = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0), - GET_MODE_SIZE (Pmode))); - new_arg = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0), - GET_MODE_SIZE (Pmode)*2)); - x = expand_expr (func, new_func, Pmode, 0); - if (x != new_func) - emit_move_insn (new_func, x); + parent = fixup->u.fixup.real_region; - x = expand_expr (arg, new_arg, Pmode, 0); - if (x != new_arg) - emit_move_insn (new_arg, x); + /* Fix up the children's parent pointers; find the end of + the list. */ + for (p = fixup->inner; ; p = p->next_peer) + { + p->outer = parent; + if (! p->next_peer) + break; + } - /* Update the cleanup chain. */ + /* In the tree of cleanups, only outer-inner ordering matters. + So link the children back in anywhere at the correct level. */ + if (parent) + pp = &parent->inner; + else + pp = &cfun->eh->region_tree; + p->next_peer = *pp; + *pp = fixup->inner; + fixup->inner = NULL; + } - x = force_operand (XEXP (buf, 0), dcc); - if (x != dcc) - emit_move_insn (dcc, x); + remove_eh_handler (fixup); + } } -/* Emit RTL to start a dynamic handler on the EH runtime dynamic - handler stack. This should only be used by expand_eh_region_start - or expand_eh_region_start_tree. */ +/* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each + can_throw instruction in the region. */ static void -start_dynamic_handler () +convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur) + rtx *pinsns; + int *orig_sp; + int cur; { - rtx dhc, dcc; - rtx arg, buf; - int size; + int *sp = orig_sp; + rtx insn, next; -#ifndef DONT_USE_BUILTIN_SETJMP - /* The number of Pmode words for the setjmp buffer, when using the - builtin setjmp/longjmp, see expand_builtin, case BUILT_IN_LONGJMP. */ - /* We use 2 words here before calling expand_builtin_setjmp. - expand_builtin_setjmp uses 2 words, and then calls emit_stack_save. - emit_stack_save needs space of size STACK_SAVEAREA_MODE (SAVE_NONLOCAL). - Subtract one, because the assign_stack_local call below adds 1. */ - size = (2 + 2 + (GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL)) - / GET_MODE_SIZE (Pmode)) - - 1); -#else -#ifdef JMP_BUF_SIZE - size = JMP_BUF_SIZE; -#else - /* Should be large enough for most systems, if it is not, - JMP_BUF_SIZE should be defined with the proper value. It will - also tend to be larger than necessary for most systems, a more - optimal port will define JMP_BUF_SIZE. */ - size = FIRST_PSEUDO_REGISTER+2; -#endif -#endif - /* XXX, FIXME: The stack space allocated this way is too long lived, - but there is no allocation routine that allocates at the level of - the last binding contour. */ - arg = assign_stack_local (BLKmode, - GET_MODE_SIZE (Pmode)*(size+1), - 0); + for (insn = *pinsns; insn ; insn = next) + { + next = NEXT_INSN (insn); + if (GET_CODE (insn) == NOTE) + { + int kind = NOTE_LINE_NUMBER (insn); + if (kind == NOTE_INSN_EH_REGION_BEG + || kind == NOTE_INSN_EH_REGION_END) + { + if (kind == NOTE_INSN_EH_REGION_BEG) + { + struct eh_region *r; - arg = change_address (arg, Pmode, NULL_RTX); + *sp++ = cur; + cur = NOTE_EH_HANDLER (insn); - /* Store dhc into the first word of the newly allocated buffer. */ + r = cfun->eh->region_array[cur]; + if (r->type == ERT_FIXUP) + { + r = r->u.fixup.real_region; + cur = r ? r->region_number : 0; + } + else if (r->type == ERT_CATCH) + { + r = r->outer; + cur = r ? r->region_number : 0; + } + } + else + cur = *--sp; + + /* Removing the first insn of a CALL_PLACEHOLDER sequence + requires extra care to adjust sequence start. */ + if (insn == *pinsns) + *pinsns = next; + remove_insn (insn); + continue; + } + } + else if (INSN_P (insn)) + { + if (cur > 0 + && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX) + /* Calls can always potentially throw exceptions, unless + they have a REG_EH_REGION note with a value of 0 or less. + Which should be the only possible kind so far. */ + && (GET_CODE (insn) == CALL_INSN + /* If we wanted exceptions for non-call insns, then + any may_trap_p instruction could throw. */ + || (flag_non_call_exceptions + && may_trap_p (PATTERN (insn))))) + { + REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur), + REG_NOTES (insn)); + } - dhc = get_dynamic_handler_chain (); - dcc = gen_rtx_MEM (Pmode, plus_constant (XEXP (arg, 0), - GET_MODE_SIZE (Pmode))); - emit_move_insn (arg, dhc); + if (GET_CODE (insn) == CALL_INSN + && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER) + { + convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 0), + sp, cur); + convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 1), + sp, cur); + convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 2), + sp, cur); + } + } + } - /* Zero out the start of the cleanup chain. */ - emit_move_insn (dcc, const0_rtx); + if (sp != orig_sp) + abort (); +} - /* The jmpbuf starts two words into the area allocated. */ - buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2); +void +convert_from_eh_region_ranges () +{ + int *stack; + rtx insns; -#ifdef DONT_USE_BUILTIN_SETJMP - { - rtx x; - x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST, - TYPE_MODE (integer_type_node), 1, - buf, Pmode); - /* If we come back here for a catch, transfer control to the handler. */ - jumpif_rtx (x, ehstack.top->entry->exception_handler_label); - } -#else - expand_builtin_setjmp_setup (buf, - ehstack.top->entry->exception_handler_label); -#endif + collect_eh_region_array (); + resolve_fixup_regions (); - /* We are committed to this, so update the handler chain. */ + stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1)); + insns = get_insns (); + convert_from_eh_region_ranges_1 (&insns, stack, 0); + free (stack); - emit_move_insn (dhc, force_operand (XEXP (arg, 0), NULL_RTX)); + remove_fixup_regions (); } -/* Start an exception handling region for the given cleanup action. - All instructions emitted after this point are considered to be part - of the region until expand_eh_region_end is invoked. CLEANUP is - the cleanup action to perform. The return value is true if the - exception region was optimized away. If that case, - expand_eh_region_end does not need to be called for this cleanup, - nor should it be. - - This routine notices one particular common case in C++ code - generation, and optimizes it so as to not need the exception - region. It works by creating a dynamic cleanup action, instead of - a using an exception region. */ - -int -expand_eh_region_start_tree (decl, cleanup) - tree decl; - tree cleanup; +void +find_exception_handler_labels () { - /* This is the old code. */ - if (! doing_eh (0)) - return 0; + rtx list = NULL_RTX; + int i; - /* The optimization only applies to actions protected with - terminate, and only applies if we are using the setjmp/longjmp - codegen method. */ - if (USING_SJLJ_EXCEPTIONS - && protect_cleanup_actions_with_terminate) - { - tree func, arg; - tree args; + free_EXPR_LIST_list (&exception_handler_labels); - /* Ignore any UNSAVE_EXPR. */ - if (TREE_CODE (cleanup) == UNSAVE_EXPR) - cleanup = TREE_OPERAND (cleanup, 0); - - /* Further, it only applies if the action is a call, if there - are 2 arguments, and if the second argument is 2. */ + if (cfun->eh->region_tree == NULL) + return; - if (TREE_CODE (cleanup) == CALL_EXPR - && (args = TREE_OPERAND (cleanup, 1)) - && (func = TREE_OPERAND (cleanup, 0)) - && (arg = TREE_VALUE (args)) - && (args = TREE_CHAIN (args)) + for (i = cfun->eh->last_region_number; i > 0; --i) + { + struct eh_region *region = cfun->eh->region_array[i]; + rtx lab; - /* is the second argument 2? */ - && TREE_CODE (TREE_VALUE (args)) == INTEGER_CST - && compare_tree_int (TREE_VALUE (args), 2) == 0 + if (! region) + continue; + if (cfun->eh->built_landing_pads) + lab = region->landing_pad; + else + lab = region->label; - /* Make sure there are no other arguments. */ - && TREE_CHAIN (args) == NULL_TREE) - { - /* Arrange for returns and gotos to pop the entry we make on the - dynamic cleanup stack. */ - expand_dcc_cleanup (decl); - start_dynamic_cleanup (func, arg); - return 1; - } + if (lab) + list = alloc_EXPR_LIST (0, lab, list); } - expand_eh_region_start_for_decl (decl); - ehstack.top->entry->finalization = cleanup; + /* For sjlj exceptions, need the return label to remain live until + after landing pad generation. */ + if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads) + list = alloc_EXPR_LIST (0, return_label, list); - return 0; + exception_handler_labels = list; } -/* Just like expand_eh_region_start, except if a cleanup action is - entered on the cleanup chain, the TREE_PURPOSE of the element put - on the chain is DECL. DECL should be the associated VAR_DECL, if - any, otherwise it should be NULL_TREE. */ - -void -expand_eh_region_start_for_decl (decl) - tree decl; + +static struct eh_region * +duplicate_eh_region_1 (o, map) + struct eh_region *o; + struct inline_remap *map; { - rtx note; + struct eh_region *n + = (struct eh_region *) xcalloc (1, sizeof (struct eh_region)); - /* This is the old code. */ - if (! doing_eh (0)) - return; + n->region_number = o->region_number + cfun->eh->last_region_number; + n->type = o->type; - /* We need a new block to record the start and end of the - dynamic handler chain. We also want to prevent jumping into - a try block. */ - expand_start_bindings (2); + switch (n->type) + { + case ERT_CLEANUP: + case ERT_MUST_NOT_THROW: + break; - /* But we don't need or want a new temporary level. */ - pop_temp_slots (); + case ERT_TRY: + if (o->u.try.continue_label) + n->u.try.continue_label + = get_label_from_map (map, + CODE_LABEL_NUMBER (o->u.try.continue_label)); + break; - /* Mark this block as created by expand_eh_region_start. This - is so that we can pop the block with expand_end_bindings - automatically. */ - mark_block_as_eh_region (); + case ERT_CATCH: + n->u.catch.type = o->u.catch.type; + break; - if (USING_SJLJ_EXCEPTIONS) + case ERT_ALLOWED_EXCEPTIONS: + n->u.allowed.type_list = o->u.allowed.type_list; + break; + + case ERT_THROW: + n->u.throw.type = o->u.throw.type; + + default: + abort (); + } + + if (o->label) + n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label)); + if (o->last) { - /* Arrange for returns and gotos to pop the entry we make on the - dynamic handler stack. */ - expand_dhc_cleanup (decl); + n->last = map->insn_map[INSN_UID (o->last)]; + if (n->last == NULL) + abort (); } - push_eh_entry (&ehstack); - note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG); - NOTE_EH_HANDLER (note) - = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label); - if (USING_SJLJ_EXCEPTIONS) - start_dynamic_handler (); + return n; } -/* Start an exception handling region. All instructions emitted after - this point are considered to be part of the region until - expand_eh_region_end is invoked. */ - -void -expand_eh_region_start () +static void +duplicate_eh_region_2 (o, n_array) + struct eh_region *o; + struct eh_region **n_array; { - expand_eh_region_start_for_decl (NULL_TREE); -} + struct eh_region *n = n_array[o->region_number]; -/* End an exception handling region. The information about the region - is found on the top of ehstack. + switch (n->type) + { + case ERT_TRY: + n->u.try.catch = n_array[o->u.try.catch->region_number]; + n->u.try.last_catch = n_array[o->u.try.last_catch->region_number]; + break; - HANDLER is either the cleanup for the exception region, or if we're - marking the end of a try block, HANDLER is integer_zero_node. + case ERT_CATCH: + if (o->u.catch.next_catch) + n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number]; + if (o->u.catch.prev_catch) + n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number]; + break; - HANDLER will be transformed to rtl when expand_leftover_cleanups - is invoked. */ + default: + break; + } -void -expand_eh_region_end (handler) - tree handler; + if (o->outer) + n->outer = n_array[o->outer->region_number]; + if (o->inner) + n->inner = n_array[o->inner->region_number]; + if (o->next_peer) + n->next_peer = n_array[o->next_peer->region_number]; +} + +int +duplicate_eh_regions (ifun, map) + struct function *ifun; + struct inline_remap *map; { - struct eh_entry *entry; - struct eh_node *node; - rtx note; - int ret, r; + int ifun_last_region_number = ifun->eh->last_region_number; + struct eh_region **n_array, *root, *cur; + int i; - if (! doing_eh (0)) - return; + if (ifun_last_region_number == 0) + return 0; - entry = pop_eh_entry (&ehstack); + n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array)); - note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END); - ret = NOTE_EH_HANDLER (note) - = CODE_LABEL_NUMBER (entry->exception_handler_label); - if (USING_SJLJ_EXCEPTIONS == 0 && ! flag_new_exceptions - /* We share outer_context between regions; only emit it once. */ - && INSN_UID (entry->outer_context) == 0) + for (i = 1; i <= ifun_last_region_number; ++i) { - rtx label; - - label = gen_label_rtx (); - emit_jump (label); - - /* Emit a label marking the end of this exception region that - is used for rethrowing into the outer context. */ - emit_label (entry->outer_context); - expand_internal_throw (); - - emit_label (label); + cur = ifun->eh->region_array[i]; + if (!cur || cur->region_number != i) + continue; + n_array[i] = duplicate_eh_region_1 (cur, map); } - - entry->finalization = handler; - - /* create region entry in final exception table */ - r = new_eh_region_entry (NOTE_EH_HANDLER (note), entry->rethrow_label); - - enqueue_eh_entry (ehqueue, entry); - - /* If we have already started ending the bindings, don't recurse. */ - if (is_eh_region ()) + for (i = 1; i <= ifun_last_region_number; ++i) { - /* Because we don't need or want a new temporary level and - because we didn't create one in expand_eh_region_start, - create a fake one now to avoid removing one in - expand_end_bindings. */ - push_temp_slots (); + cur = ifun->eh->region_array[i]; + if (!cur || cur->region_number != i) + continue; + duplicate_eh_region_2 (cur, n_array); + } - mark_block_as_not_eh_region (); + root = n_array[ifun->eh->region_tree->region_number]; + cur = cfun->eh->cur_region; + if (cur) + { + struct eh_region *p = cur->inner; + if (p) + { + while (p->next_peer) + p = p->next_peer; + p->next_peer = root; + } + else + cur->inner = root; - expand_end_bindings (NULL_TREE, 0, 0); + for (i = 1; i <= ifun_last_region_number; ++i) + if (n_array[i]->outer == NULL) + n_array[i]->outer = cur; + } + else + { + struct eh_region *p = cfun->eh->region_tree; + if (p) + { + while (p->next_peer) + p = p->next_peer; + p->next_peer = root; + } + else + cfun->eh->region_tree = root; } - /* Go through the goto handlers in the queue, emitting their - handlers if we now have enough information to do so. */ - for (node = ehqueue->head; node; node = node->chain) - if (node->entry->goto_entry_p - && node->entry->outer_context == entry->rethrow_label) - emit_cleanup_handler (node->entry); + free (n_array); - /* We can't emit handlers for goto entries until their scopes are - complete because we don't know where they need to rethrow to, - yet. */ - if (entry->finalization != integer_zero_node - && (!entry->goto_entry_p - || find_func_region_from_symbol (entry->outer_context) != -1)) - emit_cleanup_handler (entry); + i = cfun->eh->last_region_number; + cfun->eh->last_region_number = i + ifun_last_region_number; + return i; } -/* End the EH region for a goto fixup. We only need them in the region-based - EH scheme. */ + +/* ??? Move from tree.c to tree.h. */ +#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777) -void -expand_fixup_region_start () +static int +t2r_eq (pentry, pdata) + const PTR pentry; + const PTR pdata; { - if (! doing_eh (0) || USING_SJLJ_EXCEPTIONS) - return; + tree entry = (tree) pentry; + tree data = (tree) pdata; - expand_eh_region_start (); - /* Mark this entry as the entry for a goto. */ - ehstack.top->entry->goto_entry_p = 1; + return TREE_PURPOSE (entry) == data; } -/* End the EH region for a goto fixup. CLEANUP is the cleanup we just - expanded; to avoid running it twice if it throws, we look through the - ehqueue for a matching region and rethrow from its outer_context. */ +static hashval_t +t2r_hash (pentry) + const PTR pentry; +{ + tree entry = (tree) pentry; + return TYPE_HASH (TREE_PURPOSE (entry)); +} -void -expand_fixup_region_end (cleanup) - tree cleanup; +static int +t2r_mark_1 (slot, data) + PTR *slot; + PTR data ATTRIBUTE_UNUSED; { - struct eh_node *node; - int dont_issue; + tree contents = (tree) *slot; + ggc_mark_tree (contents); + return 1; +} - if (! doing_eh (0) || USING_SJLJ_EXCEPTIONS) - return; +static void +t2r_mark (addr) + PTR addr; +{ + htab_traverse (*(htab_t *)addr, t2r_mark_1, NULL); +} - for (node = ehstack.top; node && node->entry->finalization != cleanup; ) - node = node->chain; - if (node == 0) - for (node = ehqueue->head; node && node->entry->finalization != cleanup; ) - node = node->chain; - if (node == 0) - abort (); +static void +add_type_for_runtime (type) + tree type; +{ + tree *slot; - /* If the outer context label has not been issued yet, we don't want - to issue it as a part of this region, unless this is the - correct region for the outer context. If we did, then the label for - the outer context will be WITHIN the begin/end labels, - and we could get an infinte loop when it tried to rethrow, or just - generally incorrect execution following a throw. */ + slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type, + TYPE_HASH (type), INSERT); + if (*slot == NULL) + { + tree runtime = (*lang_eh_runtime_type) (type); + *slot = tree_cons (type, runtime, NULL_TREE); + } +} + +static tree +lookup_type_for_runtime (type) + tree type; +{ + tree *slot; - if (flag_new_exceptions) - dont_issue = 0; - else - dont_issue = ((INSN_UID (node->entry->outer_context) == 0) - && (ehstack.top->entry != node->entry)); + slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type, + TYPE_HASH (type), NO_INSERT); - ehstack.top->entry->outer_context = node->entry->outer_context; + /* We should have always inserrted the data earlier. */ + return TREE_VALUE (*slot); +} - /* Since we are rethrowing to the OUTER region, we know we don't need - a jump around sequence for this region, so we'll pretend the outer - context label has been issued by setting INSN_UID to 1, then clearing - it again afterwards. */ + +/* Represent an entry in @TTypes for either catch actions + or exception filter actions. */ +struct ttypes_filter +{ + tree t; + int filter; +}; - if (dont_issue) - INSN_UID (node->entry->outer_context) = 1; +/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA + (a tree) for a @TTypes type node we are thinking about adding. */ - /* Just rethrow. size_zero_node is just a NOP. */ - expand_eh_region_end (size_zero_node); +static int +ttypes_filter_eq (pentry, pdata) + const PTR pentry; + const PTR pdata; +{ + const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; + tree data = (tree) pdata; - if (dont_issue) - INSN_UID (node->entry->outer_context) = 0; + return entry->t == data; } -/* If we are using the setjmp/longjmp EH codegen method, we emit a - call to __sjthrow. Otherwise, we emit a call to __throw. */ +static hashval_t +ttypes_filter_hash (pentry) + const PTR pentry; +{ + const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; + return TYPE_HASH (entry->t); +} -void -emit_throw () +/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes + exception specification list we are thinking about adding. */ +/* ??? Currently we use the type lists in the order given. Someone + should put these in some canonical order. */ + +static int +ehspec_filter_eq (pentry, pdata) + const PTR pentry; + const PTR pdata; { - if (USING_SJLJ_EXCEPTIONS) - { - emit_library_call (sjthrow_libfunc, 0, VOIDmode, 0); - } - else - { -#ifdef JUMP_TO_THROW - emit_indirect_jump (throw_libfunc); -#else - emit_library_call (throw_libfunc, 0, VOIDmode, 0); -#endif - } - emit_barrier (); + const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; + const struct ttypes_filter *data = (const struct ttypes_filter *) pdata; + + return type_list_equal (entry->t, data->t); } -/* Throw the current exception. If appropriate, this is done by jumping - to the next handler. */ +/* Hash function for exception specification lists. */ -void -expand_internal_throw () +static hashval_t +ehspec_filter_hash (pentry) + const PTR pentry; { - emit_throw (); + const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; + hashval_t h = 0; + tree list; + + for (list = entry->t; list ; list = TREE_CHAIN (list)) + h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list)); + return h; } -/* Called from expand_exception_blocks and expand_end_catch_block to - emit any pending handlers/cleanups queued from expand_eh_region_end. */ +/* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed + up the search. Return the filter value to be used. */ -void -expand_leftover_cleanups () +static int +add_ttypes_entry (ttypes_hash, type) + htab_t ttypes_hash; + tree type; { - struct eh_entry *entry; + struct ttypes_filter **slot, *n; - for (entry = dequeue_eh_entry (ehqueue); - entry; - entry = dequeue_eh_entry (ehqueue)) + slot = (struct ttypes_filter **) + htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT); + + if ((n = *slot) == NULL) { - /* A leftover try block. Shouldn't be one here. */ - if (entry->finalization == integer_zero_node) - abort (); + /* Filter value is a 1 based table index. */ - free (entry); + n = (struct ttypes_filter *) xmalloc (sizeof (*n)); + n->t = type; + n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1; + *slot = n; + + VARRAY_PUSH_TREE (cfun->eh->ttype_data, type); } + + return n->filter; } -/* Called at the start of a block of try statements. */ -void -expand_start_try_stmts () +/* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH + to speed up the search. Return the filter value to be used. */ + +static int +add_ehspec_entry (ehspec_hash, ttypes_hash, list) + htab_t ehspec_hash; + htab_t ttypes_hash; + tree list; { - if (! doing_eh (1)) - return; + struct ttypes_filter **slot, *n; + struct ttypes_filter dummy; - expand_eh_region_start (); + dummy.t = list; + slot = (struct ttypes_filter **) + htab_find_slot (ehspec_hash, &dummy, INSERT); + + if ((n = *slot) == NULL) + { + /* Filter value is a -1 based byte index into a uleb128 buffer. */ + + n = (struct ttypes_filter *) xmalloc (sizeof (*n)); + n->t = list; + n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1); + *slot = n; + + /* Look up each type in the list and encode its filter + value as a uleb128. Terminate the list with 0. */ + for (; list ; list = TREE_CHAIN (list)) + push_uleb128 (&cfun->eh->ehspec_data, + add_ttypes_entry (ttypes_hash, TREE_VALUE (list))); + VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0); + } + + return n->filter; } -/* Called to begin a catch clause. The parameter is the object which - will be passed to the runtime type check routine. */ -void -start_catch_handler (rtime) - tree rtime; +/* Generate the action filter values to be used for CATCH and + ALLOWED_EXCEPTIONS regions. When using dwarf2 exception regions, + we use lots of landing pads, and so every type or list can share + the same filter value, which saves table space. */ + +static void +assign_filter_values () { - rtx handler_label; - int insn_region_num; - int eh_region_entry; + int i; + htab_t ttypes, ehspec; - if (! doing_eh (1)) - return; + VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data"); + VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data"); - handler_label = catchstack.top->entry->exception_handler_label; - insn_region_num = CODE_LABEL_NUMBER (handler_label); - eh_region_entry = find_func_region (insn_region_num); + ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free); + ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free); - /* If we've already issued this label, pick a new one */ - if (catchstack.top->entry->label_used) - handler_label = gen_exception_label (); - else - catchstack.top->entry->label_used = 1; + for (i = cfun->eh->last_region_number; i > 0; --i) + { + struct eh_region *r = cfun->eh->region_array[i]; - receive_exception_label (handler_label); + /* Mind we don't process a region more than once. */ + if (!r || r->region_number != i) + continue; - add_new_handler (eh_region_entry, get_new_handler (handler_label, rtime)); + switch (r->type) + { + case ERT_CATCH: + r->u.catch.filter = add_ttypes_entry (ttypes, r->u.catch.type); + break; - if (flag_new_exceptions && ! USING_SJLJ_EXCEPTIONS) - return; + case ERT_ALLOWED_EXCEPTIONS: + r->u.allowed.filter + = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list); + break; - /* Under the old mechanism, as well as setjmp/longjmp, we need to - issue code to compare 'rtime' to the value in eh_info, via the - matching function in eh_info. If its is false, we branch around - the handler we are about to issue. */ + default: + break; + } + } + + htab_delete (ttypes); + htab_delete (ehspec); +} + +static void +build_post_landing_pads () +{ + int i; - if (rtime != NULL_TREE && rtime != CATCH_ALL_TYPE) + for (i = cfun->eh->last_region_number; i > 0; --i) { - rtx call_rtx, rtime_address; + struct eh_region *region = cfun->eh->region_array[i]; + rtx seq; - if (catchstack.top->entry->false_label != NULL_RTX) + /* Mind we don't process a region more than once. */ + if (!region || region->region_number != i) + continue; + + switch (region->type) { - error ("Never issued previous false_label"); - abort (); - } - catchstack.top->entry->false_label = gen_exception_label (); + case ERT_TRY: + /* ??? Collect the set of all non-overlapping catch handlers + all the way up the chain until blocked by a cleanup. */ + /* ??? Outer try regions can share landing pads with inner + try regions if the types are completely non-overlapping, + and there are no interveaning cleanups. */ - rtime_address = expand_expr (rtime, NULL_RTX, Pmode, EXPAND_INITIALIZER); -#ifdef POINTERS_EXTEND_UNSIGNED - rtime_address = convert_memory_address (Pmode, rtime_address); -#endif - rtime_address = force_reg (Pmode, rtime_address); + region->post_landing_pad = gen_label_rtx (); - /* Now issue the call, and branch around handler if needed */ - call_rtx = emit_library_call_value (eh_rtime_match_libfunc, NULL_RTX, - LCT_NORMAL, - TYPE_MODE (integer_type_node), - 1, rtime_address, Pmode); + start_sequence (); - /* Did the function return true? */ - emit_cmp_and_jump_insns (call_rtx, const0_rtx, EQ, NULL_RTX, - GET_MODE (call_rtx), 0, 0, - catchstack.top->entry->false_label); - } -} + emit_label (region->post_landing_pad); -/* Called to end a catch clause. If we aren't using the new exception - model tabel mechanism, we need to issue the branch-around label - for the end of the catch block. */ + /* ??? It is mighty inconvenient to call back into the + switch statement generation code in expand_end_case. + Rapid prototyping sez a sequence of ifs. */ + { + struct eh_region *c; + for (c = region->u.try.catch; c ; c = c->u.catch.next_catch) + { + /* ??? _Unwind_ForcedUnwind wants no match here. */ + if (c->u.catch.type == NULL) + emit_jump (c->label); + else + emit_cmp_and_jump_insns (cfun->eh->filter, + GEN_INT (c->u.catch.filter), + EQ, NULL_RTX, word_mode, + 0, 0, c->label); + } + } -void -end_catch_handler () -{ - if (! doing_eh (1)) - return; + seq = get_insns (); + end_sequence (); - if (flag_new_exceptions && ! USING_SJLJ_EXCEPTIONS) - { - emit_barrier (); - return; - } - - /* A NULL label implies the catch clause was a catch all or cleanup */ - if (catchstack.top->entry->false_label == NULL_RTX) - return; + region->last = emit_insns_before (seq, region->u.try.catch->label); + break; - emit_label (catchstack.top->entry->false_label); - catchstack.top->entry->false_label = NULL_RTX; -} + case ERT_ALLOWED_EXCEPTIONS: + region->post_landing_pad = gen_label_rtx (); -/* Save away the current ehqueue. */ + start_sequence (); -void -push_ehqueue () -{ - struct eh_queue *q; - q = (struct eh_queue *) xcalloc (1, sizeof (struct eh_queue)); - q->next = ehqueue; - ehqueue = q; -} + emit_label (region->post_landing_pad); -/* Restore a previously pushed ehqueue. */ + emit_cmp_and_jump_insns (cfun->eh->filter, + GEN_INT (region->u.allowed.filter), + EQ, NULL_RTX, word_mode, 0, 0, + region->label); -void -pop_ehqueue () -{ - struct eh_queue *q; - expand_leftover_cleanups (); - q = ehqueue->next; - free (ehqueue); - ehqueue = q; -} + seq = get_insns (); + end_sequence (); + + region->last = emit_insns_before (seq, region->label); + break; -/* Emit the handler specified by ENTRY. */ + case ERT_CLEANUP: + case ERT_MUST_NOT_THROW: + region->post_landing_pad = region->label; + break; + + case ERT_CATCH: + case ERT_THROW: + /* Nothing to do. */ + break; + + default: + abort (); + } + } +} static void -emit_cleanup_handler (entry) - struct eh_entry *entry; +connect_post_landing_pads () { - rtx prev; - rtx handler_insns; + int i; - /* Since the cleanup could itself contain try-catch blocks, we - squirrel away the current queue and replace it when we are done - with this function. */ - push_ehqueue (); + for (i = cfun->eh->last_region_number; i > 0; --i) + { + struct eh_region *region = cfun->eh->region_array[i]; + struct eh_region *outer; + rtx before = NULL_RTX, after = NULL_RTX, seq; - /* Put these handler instructions in a sequence. */ - do_pending_stack_adjust (); - start_sequence (); + /* Mind we don't process a region more than once. */ + if (!region || region->region_number != i) + continue; - /* Emit the label for the cleanup handler for this region, and - expand the code for the handler. - - Note that a catch region is handled as a side-effect here; for a - try block, entry->finalization will contain integer_zero_node, so - no code will be generated in the expand_expr call below. But, the - label for the handler will still be emitted, so any code emitted - after this point will end up being the handler. */ - - receive_exception_label (entry->exception_handler_label); + switch (region->type) + { + case ERT_CLEANUP: + after = region->last; + if (GET_CODE (after) == BARRIER + && GET_CODE (PREV_INSN (after)) == JUMP_INSN + && GET_CODE (PATTERN (PREV_INSN (after))) == RESX) + { + before = PREV_INSN (after); + after = NULL_RTX; + } + break; - /* register a handler for this cleanup region */ - add_new_handler (find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)), - get_new_handler (entry->exception_handler_label, NULL)); + case ERT_TRY: + after = region->last; + break; - /* And now generate the insns for the cleanup handler. */ - expand_expr (entry->finalization, const0_rtx, VOIDmode, 0); + case ERT_ALLOWED_EXCEPTIONS: + before = region->label; + break; - prev = get_last_insn (); - if (prev == NULL || GET_CODE (prev) != BARRIER) - /* Code to throw out to outer context when we fall off end of the - handler. We can't do this here for catch blocks, so it's done - in expand_end_all_catch instead. */ - expand_rethrow (entry->outer_context); + case ERT_MUST_NOT_THROW: + case ERT_CATCH: + case ERT_THROW: + continue; - /* Finish this sequence. */ - do_pending_stack_adjust (); - handler_insns = get_insns (); - end_sequence (); + default: + abort (); + } - /* And add it to the CATCH_CLAUSES. */ - push_to_full_sequence (catch_clauses, catch_clauses_last); - emit_insns (handler_insns); - end_full_sequence (&catch_clauses, &catch_clauses_last); + /* If there's no fallthru, no need to add branches. */ + if (after && GET_CODE (after) == BARRIER) + continue; - /* Now we've left the handler. */ - pop_ehqueue (); -} + /* Search for another landing pad in this function. */ + for (outer = region->outer; outer ; outer = outer->outer) + if (outer->post_landing_pad) + break; -/* Generate RTL for the start of a group of catch clauses. + start_sequence (); - It is responsible for starting a new instruction sequence for the - instructions in the catch block, and expanding the handlers for the - internally-generated exception regions nested within the try block - corresponding to this catch block. */ + if (outer) + emit_jump (outer->post_landing_pad); + else + emit_library_call (unwind_resume_libfunc, LCT_NORETURN, + VOIDmode, 1, cfun->eh->exc_ptr, Pmode); -void -expand_start_all_catch () + seq = get_insns (); + end_sequence (); + if (before) + emit_insns_before (seq, before); + else + emit_insns_after (seq, after); + } +} + + +static void +dw2_build_landing_pads () { - struct eh_entry *entry; - tree label; - rtx outer_context; + int i, j; - if (! doing_eh (1)) - return; + for (i = cfun->eh->last_region_number; i > 0; --i) + { + struct eh_region *region = cfun->eh->region_array[i]; + rtx seq; - outer_context = ehstack.top->entry->outer_context; + /* Mind we don't process a region more than once. */ + if (!region || region->region_number != i) + continue; - /* End the try block. */ - expand_eh_region_end (integer_zero_node); + if (region->type != ERT_CLEANUP + && region->type != ERT_TRY + && region->type != ERT_ALLOWED_EXCEPTIONS) + continue; - emit_line_note (input_filename, lineno); - label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); + start_sequence (); - /* The label for the exception handling block that we will save. - This is Lresume in the documentation. */ - expand_label (label); - - /* Push the label that points to where normal flow is resumed onto - the top of the label stack. */ - push_label_entry (&caught_return_label_stack, NULL_RTX, label); + region->landing_pad = gen_label_rtx (); + emit_label (region->landing_pad); - /* Start a new sequence for all the catch blocks. We will add this - to the global sequence catch_clauses when we have completed all - the handlers in this handler-seq. */ - start_sequence (); +#ifdef HAVE_exception_receiver + if (HAVE_exception_receiver) + emit_insn (gen_exception_receiver ()); + else +#endif +#ifdef HAVE_nonlocal_goto_receiver + if (HAVE_nonlocal_goto_receiver) + emit_insn (gen_nonlocal_goto_receiver ()); + else +#endif + { /* Nothing */ } - /* Throw away entries in the queue that we won't need anymore. We - need entries for regions that have ended but to which there might - still be gotos pending. */ - for (entry = dequeue_eh_entry (ehqueue); - entry->finalization != integer_zero_node; - entry = dequeue_eh_entry (ehqueue)) - free (entry); + /* If the eh_return data registers are call-saved, then we + won't have considered them clobbered from the call that + threw. Kill them now. */ + for (j = 0; ; ++j) + { + unsigned r = EH_RETURN_DATA_REGNO (j); + if (r == INVALID_REGNUM) + break; + if (! call_used_regs[r]) + emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r))); + } - /* At this point, all the cleanups are done, and the ehqueue now has - the current exception region at its head. We dequeue it, and put it - on the catch stack. */ - push_entry (&catchstack, entry); + emit_move_insn (cfun->eh->exc_ptr, + gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0))); + emit_move_insn (cfun->eh->filter, + gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (1))); - /* If we are not doing setjmp/longjmp EH, because we are reordered - out of line, we arrange to rethrow in the outer context. We need to - do this because we are not physically within the region, if any, that - logically contains this catch block. */ - if (! USING_SJLJ_EXCEPTIONS) - { - expand_eh_region_start (); - ehstack.top->entry->outer_context = outer_context; - } + seq = get_insns (); + end_sequence (); + emit_insns_before (seq, region->post_landing_pad); + } } -/* Finish up the catch block. At this point all the insns for the - catch clauses have already been generated, so we only have to add - them to the catch_clauses list. We also want to make sure that if - we fall off the end of the catch clauses that we rethrow to the - outer EH region. */ + +struct sjlj_lp_info +{ + int directly_reachable; + int action_index; + int dispatch_index; + int call_site_index; +}; -void -expand_end_all_catch () +static bool +sjlj_find_directly_reachable_regions (lp_info) + struct sjlj_lp_info *lp_info; { - rtx new_catch_clause; - struct eh_entry *entry; + rtx insn; + bool found_one = false; - if (! doing_eh (1)) - return; + for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) + { + struct eh_region *region; + tree type_thrown; + rtx note; - /* Dequeue the current catch clause region. */ - entry = pop_eh_entry (&catchstack); - free (entry); + if (! INSN_P (insn)) + continue; - if (! USING_SJLJ_EXCEPTIONS) - { - rtx outer_context = ehstack.top->entry->outer_context; + note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + if (!note || INTVAL (XEXP (note, 0)) <= 0) + continue; - /* Finish the rethrow region. size_zero_node is just a NOP. */ - expand_eh_region_end (size_zero_node); - /* New exceptions handling models will never have a fall through - of a catch clause */ - if (!flag_new_exceptions) - expand_rethrow (outer_context); - } - else - expand_rethrow (NULL_RTX); + region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; - /* Code to throw out to outer context, if we fall off end of catch - handlers. This is rethrow (Lresume, same id, same obj) in the - documentation. We use Lresume because we know that it will throw - to the correct context. + type_thrown = NULL_TREE; + if (region->type == ERT_THROW) + { + type_thrown = region->u.throw.type; + region = region->outer; + } - In other words, if the catch handler doesn't exit or return, we - do a "throw" (using the address of Lresume as the point being - thrown from) so that the outer EH region can then try to process - the exception. */ + /* Find the first containing region that might handle the exception. + That's the landing pad to which we will transfer control. */ + for (; region; region = region->outer) + if (reachable_next_level (region, type_thrown, 0) != RNL_NOT_CAUGHT) + break; - /* Now we have the complete catch sequence. */ - new_catch_clause = get_insns (); - end_sequence (); - - /* This level of catch blocks is done, so set up the successful - catch jump label for the next layer of catch blocks. */ - pop_label_entry (&caught_return_label_stack); - pop_label_entry (&outer_context_label_stack); - - /* Add the new sequence of catches to the main one for this function. */ - push_to_full_sequence (catch_clauses, catch_clauses_last); - emit_insns (new_catch_clause); - end_full_sequence (&catch_clauses, &catch_clauses_last); - - /* Here we fall through into the continuation code. */ -} + if (region) + { + lp_info[region->region_number].directly_reachable = 1; + found_one = true; + } + } -/* Rethrow from the outer context LABEL. */ + return found_one; +} static void -expand_rethrow (label) - rtx label; +sjlj_assign_call_site_values (dispatch_label, lp_info) + rtx dispatch_label; + struct sjlj_lp_info *lp_info; { - if (USING_SJLJ_EXCEPTIONS) - emit_throw (); - else - if (flag_new_exceptions) + htab_t ar_hash; + int i, index; + + /* First task: build the action table. */ + + VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data"); + ar_hash = htab_create (31, action_record_hash, action_record_eq, free); + + for (i = cfun->eh->last_region_number; i > 0; --i) + if (lp_info[i].directly_reachable) { - rtx insn; - int region; - if (label == NULL_RTX) - label = last_rethrow_symbol; - emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode); - region = find_func_region (eh_region_from_symbol (label)); - /* If the region is -1, it doesn't exist yet. We shouldn't be - trying to rethrow there yet. */ - if (region == -1) - abort (); - function_eh_regions[region].rethrow_ref = 1; - - /* Search backwards for the actual call insn. */ - insn = get_last_insn (); - while (GET_CODE (insn) != CALL_INSN) - insn = PREV_INSN (insn); - delete_insns_since (insn); - - /* Mark the label/symbol on the call. */ - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_RETHROW, label, - REG_NOTES (insn)); - emit_barrier (); + struct eh_region *r = cfun->eh->region_array[i]; + r->landing_pad = dispatch_label; + lp_info[i].action_index = collect_one_action_chain (ar_hash, r); + if (lp_info[i].action_index != -1) + cfun->uses_eh_lsda = 1; } - else - emit_jump (label); -} -/* Begin a region that will contain entries created with - add_partial_entry. */ + htab_delete (ar_hash); -void -begin_protect_partials () -{ - /* Push room for a new list. */ - protect_list = tree_cons (NULL_TREE, NULL_TREE, protect_list); -} + /* Next: assign dispatch values. In dwarf2 terms, this would be the + landing pad label for the region. For sjlj though, there is one + common landing pad from which we dispatch to the post-landing pads. -/* End all the pending exception regions on protect_list. The handlers - will be emitted when expand_leftover_cleanups is invoked. */ + A region receives a dispatch index if it is directly reachable + and requires in-function processing. Regions that share post-landing + pads may share dispatch indicies. */ + /* ??? Post-landing pad sharing doesn't actually happen at the moment + (see build_post_landing_pads) so we don't bother checking for it. */ -void -end_protect_partials () -{ - tree t; - - /* For backwards compatibility, we allow callers to omit the call to - begin_protect_partials for the outermost region. So, - PROTECT_LIST may be NULL. */ - if (!protect_list) - return; + index = 0; + for (i = cfun->eh->last_region_number; i > 0; --i) + if (lp_info[i].directly_reachable + && lp_info[i].action_index >= 0) + lp_info[i].dispatch_index = index++; - /* End all the exception regions. */ - for (t = TREE_VALUE (protect_list); t; t = TREE_CHAIN (t)) - expand_eh_region_end (TREE_VALUE (t)); + /* Finally: assign call-site values. If dwarf2 terms, this would be + the region number assigned by convert_to_eh_region_ranges, but + handles no-action and must-not-throw differently. */ - /* Pop the topmost entry. */ - protect_list = TREE_CHAIN (protect_list); - + call_site_base = 1; + for (i = cfun->eh->last_region_number; i > 0; --i) + if (lp_info[i].directly_reachable) + { + int action = lp_info[i].action_index; + + /* Map must-not-throw to otherwise unused call-site index 0. */ + if (action == -2) + index = 0; + /* Map no-action to otherwise unused call-site index -1. */ + else if (action == -1) + index = -1; + /* Otherwise, look it up in the table. */ + else + index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action); + + lp_info[i].call_site_index = index; + } } -/* Arrange for __terminate to be called if there is an unhandled throw - from within E. */ - -tree -protect_with_terminate (e) - tree e; +static void +sjlj_mark_call_sites (lp_info) + struct sjlj_lp_info *lp_info; { - /* We only need to do this when using setjmp/longjmp EH and the - language requires it, as otherwise we protect all of the handlers - at once, if we need to. */ - if (USING_SJLJ_EXCEPTIONS && protect_cleanup_actions_with_terminate) + int last_call_site = -2; + rtx insn, mem; + + mem = change_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node), + plus_constant (XEXP (cfun->eh->sjlj_fc, 0), + sjlj_fc_call_site_ofs)); + + for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) { - tree handler, result; + struct eh_region *region; + int this_call_site; + rtx note, before, p; - handler = make_node (RTL_EXPR); - TREE_TYPE (handler) = void_type_node; - RTL_EXPR_RTL (handler) = const0_rtx; - TREE_SIDE_EFFECTS (handler) = 1; - start_sequence_for_rtl_expr (handler); + /* Reset value tracking at extended basic block boundaries. */ + if (GET_CODE (insn) == CODE_LABEL) + last_call_site = -2; - emit_library_call (terminate_libfunc, 0, VOIDmode, 0); - emit_barrier (); + if (! INSN_P (insn)) + continue; - RTL_EXPR_SEQUENCE (handler) = get_insns (); - end_sequence (); - - result = build (TRY_CATCH_EXPR, TREE_TYPE (e), e, handler); - TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e); - TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e); - TREE_READONLY (result) = TREE_READONLY (e); + note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + if (!note) + { + /* Calls (and trapping insns) without notes are outside any + exception handling region in this function. Mark them as + no action. */ + if (GET_CODE (insn) == CALL_INSN + || (flag_non_call_exceptions + && may_trap_p (PATTERN (insn)))) + this_call_site = -1; + else + continue; + } + else + { + /* Calls that are known to not throw need not be marked. */ + if (INTVAL (XEXP (note, 0)) <= 0) + continue; - e = result; - } + region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; + this_call_site = lp_info[region->region_number].call_site_index; + } - return e; -} - -/* The exception table that we build that is used for looking up and - dispatching exceptions, the current number of entries, and its - maximum size before we have to extend it. + if (this_call_site == last_call_site) + continue; + + /* Don't separate a call from it's argument loads. */ + before = insn; + if (GET_CODE (insn) == CALL_INSN) + { + HARD_REG_SET parm_regs; + int nparm_regs; + + /* Since different machines initialize their parameter registers + in different orders, assume nothing. Collect the set of all + parameter registers. */ + CLEAR_HARD_REG_SET (parm_regs); + nparm_regs = 0; + for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1)) + if (GET_CODE (XEXP (p, 0)) == USE + && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG) + { + if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER) + abort (); + + SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0))); + nparm_regs++; + } + + /* Search backward for the first set of a register in this set. */ + while (nparm_regs) + { + before = PREV_INSN (before); - The number in eh_table is the code label number of the exception - handler for the region. This is added by add_eh_table_entry and - used by output_exception_table_entry. */ + /* Given that we've done no other optimizations yet, + the arguments should be immediately available. */ + if (GET_CODE (before) == CODE_LABEL) + abort (); -static int *eh_table = NULL; -static int eh_table_size = 0; -static int eh_table_max_size = 0; + p = single_set (before); + if (p && GET_CODE (SET_DEST (p)) == REG + && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER + && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)))) + { + CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))); + nparm_regs--; + } + } + } -/* Note the need for an exception table entry for region N. If we - don't need to output an explicit exception table, avoid all of the - extra work. + start_sequence (); + emit_move_insn (mem, GEN_INT (this_call_site)); + p = get_insns (); + end_sequence (); - Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen. - (Or NOTE_INSN_EH_REGION_END sometimes) - N is the NOTE_EH_HANDLER of the note, which comes from the code - label number of the exception handler for the region. */ + emit_insns_before (p, before); + last_call_site = this_call_site; + } +} -void -add_eh_table_entry (n) - int n; +/* Construct the SjLj_Function_Context. */ + +static void +sjlj_emit_function_enter (dispatch_label) + rtx dispatch_label; { -#ifndef OMIT_EH_TABLE - if (eh_table_size >= eh_table_max_size) - { - if (eh_table) - { - eh_table_max_size += eh_table_max_size>>1; + rtx fn_begin, fc, mem, seq; - if (eh_table_max_size < 0) - abort (); + fc = cfun->eh->sjlj_fc; - eh_table = (int *) xrealloc (eh_table, - eh_table_max_size * sizeof (int)); - } - else - { - eh_table_max_size = 252; - eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int)); - } - } - eh_table[eh_table_size++] = n; - - if (flag_new_exceptions) - { - /* We will output the exception table late in the compilation. That - references type_info objects which should have already been output - by that time. We explicitly mark those objects as being - referenced now so we know to emit them. */ - struct handler_info *handler = get_first_handler (n); - - for (; handler; handler = handler->next) - if (handler->type_info && handler->type_info != CATCH_ALL_TYPE) - { - tree tinfo = (tree)handler->type_info; + start_sequence (); - tinfo = TREE_OPERAND (tinfo, 0); - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1; - } + mem = change_address (fc, Pmode, + plus_constant (XEXP (fc, 0), sjlj_fc_personality_ofs)); + emit_move_insn (mem, eh_personality_libfunc); + + mem = change_address (fc, Pmode, + plus_constant (XEXP (fc, 0), sjlj_fc_lsda_ofs)); + if (cfun->uses_eh_lsda) + { + char buf[20]; + ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", sjlj_funcdef_number); + emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf))); } + else + emit_move_insn (mem, const0_rtx); + +#ifdef DONT_USE_BUILTIN_SETJMP + { + rtx x, note; + x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_NORMAL, + TYPE_MODE (integer_type_node), 1, + plus_constant (XEXP (fc, 0), + sjlj_fc_jbuf_ofs), Pmode); + + note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE); + NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx); + + emit_cmp_and_jump_insns (x, const0_rtx, NE, 0, + TYPE_MODE (integer_type_node), 0, 0, + dispatch_label); + } +#else + expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs), + dispatch_label); #endif -} -/* Return a non-zero value if we need to output an exception table. + emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode, + 1, XEXP (fc, 0), Pmode); - On some platforms, we don't have to output a table explicitly. - This routine doesn't mean we don't have one. */ + seq = get_insns (); + end_sequence (); -int -exception_table_p () -{ - if (eh_table) - return 1; + /* ??? Instead of doing this at the beginning of the function, + do this in a block that is at loop level 0 and dominates all + can_throw_internal instructions. */ - return 0; + for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin)) + if (GET_CODE (fn_begin) == NOTE + && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG) + break; + emit_insns_after (seq, fn_begin); } -/* Output the entry of the exception table corresponding to the - exception region numbered N to file FILE. +/* Call back from expand_function_end to know where we should put + the call to unwind_sjlj_unregister_libfunc if needed. */ - N is the code label number corresponding to the handler of the - region. */ +void +sjlj_emit_function_exit_after (after) + rtx after; +{ + cfun->eh->sjlj_exit_after = after; +} static void -output_exception_table_entry (file, n) - FILE *file; - int n; -{ - char buf[256]; - rtx sym; - struct handler_info *handler = get_first_handler (n); - int index = find_func_region (n); - rtx rethrow; - - /* Form and emit the rethrow label, if needed */ - if (flag_new_exceptions - && (handler || function_eh_regions[index].rethrow_ref)) - rethrow = function_eh_regions[index].rethrow_label; - else - rethrow = NULL_RTX; +sjlj_emit_function_exit () +{ + rtx seq; - if (function_eh_regions[index].emitted) - return; - function_eh_regions[index].emitted = 1; + start_sequence (); - for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next) - { - /* rethrow label should indicate the LAST entry for a region */ - if (rethrow != NULL_RTX && (handler == NULL || handler->next == NULL)) - { - ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", n); - assemble_eh_label(buf); - rethrow = NULL_RTX; - } + emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode, + 1, XEXP (cfun->eh->sjlj_fc, 0), Pmode); - ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n); - sym = gen_rtx_SYMBOL_REF (Pmode, buf); - assemble_eh_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1); + seq = get_insns (); + end_sequence (); - ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n); - sym = gen_rtx_SYMBOL_REF (Pmode, buf); - assemble_eh_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1); - - if (handler == NULL) - assemble_eh_integer (GEN_INT (0), POINTER_SIZE / BITS_PER_UNIT, 1); - else - { - ASM_GENERATE_INTERNAL_LABEL (buf, "L", handler->handler_number); - sym = gen_rtx_SYMBOL_REF (Pmode, buf); - assemble_eh_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1); - } - - if (flag_new_exceptions) - { - if (handler == NULL || handler->type_info == NULL) - assemble_eh_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); - else - if (handler->type_info == CATCH_ALL_TYPE) - assemble_eh_integer (GEN_INT (CATCH_ALL_TYPE), - POINTER_SIZE / BITS_PER_UNIT, 1); - else - output_constant ((tree)(handler->type_info), - POINTER_SIZE / BITS_PER_UNIT); - } - putc ('\n', file); /* blank line */ - /* We only output the first label under the old scheme */ - if (! flag_new_exceptions || handler == NULL) - break; - } -} - -/* Output the exception table if we have and need one. */ - -static short language_code = 0; -static short version_code = 0; - -/* This routine will set the language code for exceptions. */ -void -set_exception_lang_code (code) - int code; -{ - language_code = code; -} + /* ??? Really this can be done in any block at loop level 0 that + post-dominates all can_throw_internal instructions. This is + the last possible moment. */ -/* This routine will set the language version code for exceptions. */ -void -set_exception_version_code (code) - int code; -{ - version_code = code; + emit_insns_after (seq, cfun->eh->sjlj_exit_after); } -/* Free the EH table structures. */ -void -free_exception_table () +static void +sjlj_emit_dispatch_table (dispatch_label, lp_info) + rtx dispatch_label; + struct sjlj_lp_info *lp_info; { - if (eh_table) - free (eh_table); - clear_function_eh_region (); -} + int i, first_reachable; + rtx mem, dispatch, seq, fc; + + fc = cfun->eh->sjlj_fc; + + start_sequence (); + + emit_label (dispatch_label); -/* Output the common content of an exception table. */ -void -output_exception_table_data () -{ - int i; - char buf[256]; - extern FILE *asm_out_file; +#ifndef DONT_USE_BUILTIN_SETJMP + expand_builtin_setjmp_receiver (dispatch_label); +#endif + + /* Load up dispatch index, exc_ptr and filter values from the + function context. */ + mem = change_address (fc, TYPE_MODE (integer_type_node), + plus_constant (XEXP (fc, 0), sjlj_fc_call_site_ofs)); + dispatch = copy_to_reg (mem); + + mem = change_address (fc, word_mode, + plus_constant (XEXP (fc, 0), sjlj_fc_data_ofs)); + if (word_mode != Pmode) + { +#ifdef POINTERS_EXTEND_UNSIGNED + mem = convert_memory_address (Pmode, mem); +#else + mem = convert_to_mode (Pmode, mem, 0); +#endif + } + emit_move_insn (cfun->eh->exc_ptr, mem); + + mem = change_address (fc, word_mode, + plus_constant (XEXP (fc, 0), + sjlj_fc_data_ofs + UNITS_PER_WORD)); + emit_move_insn (cfun->eh->filter, mem); - if (flag_new_exceptions) + /* Jump to one of the directly reachable regions. */ + /* ??? This really ought to be using a switch statement. */ + + first_reachable = 0; + for (i = cfun->eh->last_region_number; i > 0; --i) { - assemble_eh_integer (GEN_INT (NEW_EH_RUNTIME), - POINTER_SIZE / BITS_PER_UNIT, 1); - assemble_eh_integer (GEN_INT (language_code), 2 , 1); - assemble_eh_integer (GEN_INT (version_code), 2 , 1); + if (! lp_info[i].directly_reachable + || lp_info[i].action_index < 0) + continue; - /* Add enough padding to make sure table aligns on a pointer boundry. */ - i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4; - for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT) - ; - if (i != 0) - assemble_eh_integer (const0_rtx, i , 1); + if (! first_reachable) + { + first_reachable = i; + continue; + } - /* Generate the label for offset calculations on rethrows. */ - ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0); - assemble_eh_label(buf); + emit_cmp_and_jump_insns (dispatch, + GEN_INT (lp_info[i].dispatch_index), EQ, + NULL_RTX, TYPE_MODE (integer_type_node), 0, 0, + cfun->eh->region_array[i]->post_landing_pad); } - for (i = 0; i < eh_table_size; ++i) - output_exception_table_entry (asm_out_file, eh_table[i]); + seq = get_insns (); + end_sequence (); + emit_insns_before (seq, (cfun->eh->region_array[first_reachable] + ->post_landing_pad)); } -/* Output an exception table for the entire compilation unit. */ -void -output_exception_table () +static void +sjlj_build_landing_pads () { - char buf[256]; - extern FILE *asm_out_file; - - if (! doing_eh (0) || ! eh_table) - return; + struct sjlj_lp_info *lp_info; - exception_section (); + lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1, + sizeof (struct sjlj_lp_info)); - /* Beginning marker for table. */ - assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode)); - assemble_eh_label ("__EXCEPTION_TABLE__"); + if (sjlj_find_directly_reachable_regions (lp_info)) + { + rtx dispatch_label = gen_label_rtx (); - output_exception_table_data (); + cfun->eh->sjlj_fc + = assign_stack_local (TYPE_MODE (sjlj_fc_type_node), + int_size_in_bytes (sjlj_fc_type_node), + TYPE_ALIGN (sjlj_fc_type_node)); - /* Ending marker for table. */ - /* Generate the label for end of table. */ - ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", CODE_LABEL_NUMBER (final_rethrow)); - assemble_eh_label(buf); - assemble_eh_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); + sjlj_assign_call_site_values (dispatch_label, lp_info); + sjlj_mark_call_sites (lp_info); - /* For binary compatibility, the old __throw checked the second - position for a -1, so we should output at least 2 -1's */ - if (! flag_new_exceptions) - assemble_eh_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); + sjlj_emit_function_enter (dispatch_label); + sjlj_emit_dispatch_table (dispatch_label, lp_info); + sjlj_emit_function_exit (); + } - putc ('\n', asm_out_file); /* blank line */ + free (lp_info); } -/* Used by the ia64 unwind format to output data for an individual - function. */ void -output_function_exception_table () +finish_eh_generation () { - extern FILE *asm_out_file; - - if (! doing_eh (0) || ! eh_table) + /* Nothing to do if no regions created. */ + if (cfun->eh->region_tree == NULL) return; -#ifdef HANDLER_SECTION - HANDLER_SECTION; -#endif - - output_exception_table_data (); + /* The object here is to provide find_basic_blocks with detailed + information (via reachable_handlers) on how exception control + flows within the function. In this first pass, we can include + type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS + regions, and hope that it will be useful in deleting unreachable + handlers. Subsequently, we will generate landing pads which will + connect many of the handlers, and then type information will not + be effective. Still, this is a win over previous implementations. */ + + jump_optimize_minimal (get_insns ()); + find_basic_blocks (get_insns (), max_reg_num (), 0); + cleanup_cfg (); + + /* These registers are used by the landing pads. Make sure they + have been generated. */ + get_exception_pointer (); + cfun->eh->filter = gen_reg_rtx (word_mode); + + /* Construct the landing pads. */ + + assign_filter_values (); + build_post_landing_pads (); + connect_post_landing_pads (); + if (USING_SJLJ_EXCEPTIONS) + sjlj_build_landing_pads (); + else + dw2_build_landing_pads (); - /* Ending marker for table. */ - assemble_eh_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); + cfun->eh->built_landing_pads = 1; - putc ('\n', asm_out_file); /* blank line */ + /* We've totally changed the CFG. Start over. */ + find_exception_handler_labels (); + jump_optimize_minimal (get_insns ()); + find_basic_blocks (get_insns (), max_reg_num (), 0); + cleanup_cfg (); } - -/* Emit code to get EH context. - - We have to scan thru the code to find possible EH context registers. - Inlined functions may use it too, and thus we'll have to be able - to change them too. +/* This section handles removing dead code for flow. */ - This is done only if using USING_SJLJ_EXCEPTIONS. */ +/* Remove LABEL from the exception_handler_labels list. */ -void -emit_eh_context () +static void +remove_exception_handler_label (label) + rtx label; { - rtx insn; - rtx ehc = 0; - - if (! doing_eh (0)) - return; - - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (GET_CODE (insn) == INSN - && GET_CODE (PATTERN (insn)) == USE) - { - rtx reg = find_reg_note (insn, REG_EH_CONTEXT, 0); - if (reg) - { - rtx insns; - - start_sequence (); + rtx *pl, l; - /* If this is the first use insn, emit the call here. This - will always be at the top of our function, because if - expand_inline_function notices a REG_EH_CONTEXT note, it - adds a use insn to this function as well. */ - if (ehc == 0) - ehc = call_get_eh_context (); + for (pl = &exception_handler_labels, l = *pl; + XEXP (l, 0) != label; + pl = &XEXP (l, 1), l = *pl) + continue; - emit_move_insn (XEXP (reg, 0), ehc); - insns = get_insns (); - end_sequence (); - - emit_insns_before (insns, insn); - } - } + *pl = XEXP (l, 1); + free_EXPR_LIST_node (l); } -/* Scan the insn chain F and build a list of handler labels. The - resulting list is placed in the global variable exception_handler_labels. */ +/* Splice REGION from the region tree etc. */ static void -find_exception_handler_labels_1 (f) - rtx f; +remove_eh_handler (region) + struct eh_region *region; { - rtx insn; + struct eh_region **pp, *p; + rtx lab; + int i; - /* For each start of a region, add its label to the list. */ + /* For the benefit of efficiently handling REG_EH_REGION notes, + replace this region in the region array with its containing + region. Note that previous region deletions may result in + multiple copies of this region in the array, so we have to + search the whole thing. */ + for (i = cfun->eh->last_region_number; i > 0; --i) + if (cfun->eh->region_array[i] == region) + cfun->eh->region_array[i] = region->outer; + + if (cfun->eh->built_landing_pads) + lab = region->landing_pad; + else + lab = region->label; + if (lab) + remove_exception_handler_label (lab); + + if (region->outer) + pp = ®ion->outer->inner; + else + pp = &cfun->eh->region_tree; + for (p = *pp; p != region; pp = &p->next_peer, p = *pp) + continue; - for (insn = f; insn; insn = NEXT_INSN (insn)) + if (region->inner) { - struct handler_info* ptr; - if (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - { - ptr = get_first_handler (NOTE_EH_HANDLER (insn)); - for ( ; ptr; ptr = ptr->next) - { - /* make sure label isn't in the list already */ - rtx x; - for (x = exception_handler_labels; x; x = XEXP (x, 1)) - if (XEXP (x, 0) == ptr->handler_label) - break; - if (! x) - exception_handler_labels = gen_rtx_EXPR_LIST (VOIDmode, - ptr->handler_label, exception_handler_labels); - } - } - else if (GET_CODE (insn) == CALL_INSN - && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER) - { - find_exception_handler_labels_1 (XEXP (PATTERN (insn), 0)); - find_exception_handler_labels_1 (XEXP (PATTERN (insn), 1)); - find_exception_handler_labels_1 (XEXP (PATTERN (insn), 2)); - } + for (p = region->inner; p->next_peer ; p = p->next_peer) + p->outer = region->outer; + p->next_peer = region->next_peer; + p->outer = region->outer; + *pp = region->inner; } -} - -/* Scan the current insns and build a list of handler labels. The - resulting list is placed in the global variable exception_handler_labels. + else + *pp = region->next_peer; - It is called after the last exception handling region is added to - the current function (when the rtl is almost all built for the - current function) and before the jump optimization pass. */ -void -find_exception_handler_labels () -{ - exception_handler_labels = NULL_RTX; + if (region->type == ERT_CATCH) + { + struct eh_region *try, *next, *prev; - /* If we aren't doing exception handling, there isn't much to check. */ - if (! doing_eh (0)) - return; + for (try = region->next_peer; + try->type == ERT_CATCH; + try = try->next_peer) + continue; + if (try->type != ERT_TRY) + abort (); - find_exception_handler_labels_1 (get_insns ()); -} + next = region->u.catch.next_catch; + prev = region->u.catch.prev_catch; -/* Return a value of 1 if the parameter label number is an exception handler - label. Return 0 otherwise. */ + if (next) + next->u.catch.prev_catch = prev; + else + try->u.try.last_catch = prev; + if (prev) + prev->u.catch.next_catch = next; + else + { + try->u.try.catch = next; + if (! next) + remove_eh_handler (try); + } + } -int -is_exception_handler_label (lab) - int lab; -{ - rtx x; - for (x = exception_handler_labels ; x ; x = XEXP (x, 1)) - if (lab == CODE_LABEL_NUMBER (XEXP (x, 0))) - return 1; - return 0; + free (region); } -/* Perform sanity checking on the exception_handler_labels list. - - Can be called after find_exception_handler_labels is called to - build the list of exception handlers for the current function and - before we finish processing the current function. */ +/* LABEL heads a basic block that is about to be deleted. If this + label corresponds to an exception region, we may be able to + delete the region. */ void -check_exception_handler_labels () +maybe_remove_eh_handler (label) + rtx label; { - rtx insn, insn2; + int i; - /* If we aren't doing exception handling, there isn't much to check. */ - if (! doing_eh (0)) + /* ??? After generating landing pads, it's not so simple to determine + if the region data is completely unused. One must examine the + landing pad and the post landing pad, and whether an inner try block + is referencing the catch handlers directly. */ + if (cfun->eh->built_landing_pads) return; - /* Make sure there is no more than 1 copy of a label */ - for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1)) - { - int count = 0; - for (insn2 = exception_handler_labels; insn2; insn2 = XEXP (insn2, 1)) - if (XEXP (insn, 0) == XEXP (insn2, 0)) - count++; - if (count != 1) - warning ("Counted %d copies of EH region %d in list.\n", count, - CODE_LABEL_NUMBER (insn)); - } - -} - -/* Mark the children of NODE for GC. */ - -static void -mark_eh_node (node) - struct eh_node *node; -{ - while (node) + for (i = cfun->eh->last_region_number; i > 0; --i) { - if (node->entry) + struct eh_region *region = cfun->eh->region_array[i]; + if (region && region->label == label) { - ggc_mark_rtx (node->entry->outer_context); - ggc_mark_rtx (node->entry->exception_handler_label); - ggc_mark_tree (node->entry->finalization); - ggc_mark_rtx (node->entry->false_label); - ggc_mark_rtx (node->entry->rethrow_label); + /* Flow will want to remove MUST_NOT_THROW regions as unreachable + because there is no path to the fallback call to terminate. + But the region continues to affect call-site data until there + are no more contained calls, which we don't see here. */ + if (region->type == ERT_MUST_NOT_THROW) + { + remove_exception_handler_label (region->label); + region->label = NULL_RTX; + } + else + remove_eh_handler (region); + break; } - node = node ->chain; } } -/* Mark S for GC. */ + +/* This section describes CFG exception edges for flow. */ -static void -mark_eh_stack (s) - struct eh_stack *s; +/* For communicating between calls to reachable_next_level. */ +struct reachable_info { - if (s) - mark_eh_node (s->top); -} + tree types_caught; + tree types_allowed; + rtx handlers; +}; -/* Mark Q for GC. */ +/* A subroutine of reachable_next_level. Return true if TYPE, or a + base class of TYPE, is in HANDLED. */ -static void -mark_eh_queue (q) - struct eh_queue *q; +static int +check_handled (handled, type) + tree handled, type; { - while (q) + tree t; + + /* We can check for exact matches without front-end help. */ + if (! lang_eh_type_covers) { - mark_eh_node (q->head); - q = q->next; + for (t = handled; t ; t = TREE_CHAIN (t)) + if (TREE_VALUE (t) == type) + return 1; + } + else + { + for (t = handled; t ; t = TREE_CHAIN (t)) + if ((*lang_eh_type_covers) (TREE_VALUE (t), type)) + return 1; } + + return 0; } -/* Mark NODE for GC. A label_node contains a union containing either - a tree or an rtx. This label_node will contain a tree. */ +/* A subroutine of reachable_next_level. If we are collecting a list + of handlers, add one. After landing pad generation, reference + it instead of the handlers themselves. Further, the handlers are + all wired together, so by referencing one, we've got them all. + Before landing pad generation we reference each handler individually. + + LP_REGION contains the landing pad; REGION is the handler. */ static void -mark_tree_label_node (node) - struct label_node *node; +add_reachable_handler (info, lp_region, region) + struct reachable_info *info; + struct eh_region *lp_region; + struct eh_region *region; { - while (node) + if (! info) + return; + + if (cfun->eh->built_landing_pads) { - ggc_mark_tree (node->u.tlabel); - node = node->chain; + if (! info->handlers) + info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX); } + else + info->handlers = alloc_INSN_LIST (region->label, info->handlers); } -/* Mark EH for GC. */ +/* Process one level of exception regions for reachability. + If TYPE_THROWN is non-null, then it is the *exact* type being + propagated. If INFO is non-null, then collect handler labels + and caught/allowed type information between invocations. */ -void -mark_eh_status (eh) - struct eh_status *eh; +static enum reachable_code +reachable_next_level (region, type_thrown, info) + struct eh_region *region; + tree type_thrown; + struct reachable_info *info; { - if (eh == 0) - return; + switch (region->type) + { + case ERT_CLEANUP: + /* Before landing-pad generation, we model control flow + directly to the individual handlers. In this way we can + see that catch handler types may shadow one another. */ + add_reachable_handler (info, region, region); + return RNL_MAYBE_CAUGHT; + + case ERT_TRY: + { + struct eh_region *c; + enum reachable_code ret = RNL_NOT_CAUGHT; - mark_eh_stack (&eh->x_ehstack); - mark_eh_stack (&eh->x_catchstack); - mark_eh_queue (eh->x_ehqueue); - ggc_mark_rtx (eh->x_catch_clauses); + for (c = region->u.try.catch; c ; c = c->u.catch.next_catch) + { + /* A catch-all handler ends the search. */ + /* ??? _Unwind_ForcedUnwind will want outer cleanups + to be run as well. */ + if (c->u.catch.type == NULL) + { + add_reachable_handler (info, region, c); + return RNL_CAUGHT; + } + + if (type_thrown) + { + /* If we have a type match, end the search. */ + if (c->u.catch.type == type_thrown + || (lang_eh_type_covers + && (*lang_eh_type_covers) (c->u.catch.type, + type_thrown))) + { + add_reachable_handler (info, region, c); + return RNL_CAUGHT; + } + + /* If we have definitive information of a match failure, + the catch won't trigger. */ + if (lang_eh_type_covers) + return RNL_NOT_CAUGHT; + } + + if (! info) + ret = RNL_MAYBE_CAUGHT; + + /* A type must not have been previously caught. */ + else if (! check_handled (info->types_caught, c->u.catch.type)) + { + add_reachable_handler (info, region, c); + info->types_caught = tree_cons (NULL, c->u.catch.type, + info->types_caught); + + /* ??? If the catch type is a base class of every allowed + type, then we know we can stop the search. */ + ret = RNL_MAYBE_CAUGHT; + } + } - if (lang_mark_false_label_stack) - (*lang_mark_false_label_stack) (eh->x_false_label_stack); - mark_tree_label_node (eh->x_caught_return_label_stack); + return ret; + } - ggc_mark_tree (eh->x_protect_list); - ggc_mark_rtx (eh->ehc); - ggc_mark_rtx (eh->x_eh_return_stub_label); -} + case ERT_ALLOWED_EXCEPTIONS: + /* An empty list of types definitely ends the search. */ + if (region->u.allowed.type_list == NULL_TREE) + { + add_reachable_handler (info, region, region); + return RNL_CAUGHT; + } -/* Mark ARG (which is really a struct func_eh_entry**) for GC. */ + /* Collect a list of lists of allowed types for use in detecting + when a catch may be transformed into a catch-all. */ + if (info) + info->types_allowed = tree_cons (NULL_TREE, + region->u.allowed.type_list, + info->types_allowed); + + /* If we have definitive information about the type heirarchy, + then we can tell if the thrown type will pass through the + filter. */ + if (type_thrown && lang_eh_type_covers) + { + if (check_handled (region->u.allowed.type_list, type_thrown)) + return RNL_NOT_CAUGHT; + else + { + add_reachable_handler (info, region, region); + return RNL_CAUGHT; + } + } -static void -mark_func_eh_entry (arg) - void *arg; -{ - struct func_eh_entry *fee; - struct handler_info *h; - int i; + add_reachable_handler (info, region, region); + return RNL_MAYBE_CAUGHT; - fee = *((struct func_eh_entry **) arg); + case ERT_CATCH: + /* Catch regions are handled by their controling try region. */ + return RNL_NOT_CAUGHT; - for (i = 0; i < current_func_eh_entry; ++i) - { - ggc_mark_rtx (fee->rethrow_label); - for (h = fee->handlers; h; h = h->next) + case ERT_MUST_NOT_THROW: + /* Here we end our search, since no exceptions may propagate. + If we've touched down at some landing pad previous, then the + explicit function call we generated may be used. Otherwise + the call is made by the runtime. */ + if (info && info->handlers) { - ggc_mark_rtx (h->handler_label); - if (h->type_info != CATCH_ALL_TYPE) - ggc_mark_tree ((tree) h->type_info); + add_reachable_handler (info, region, region); + return RNL_CAUGHT; } + else + return RNL_BLOCKED; - /* Skip to the next entry in the array. */ - ++fee; + case ERT_THROW: + case ERT_FIXUP: + /* Shouldn't see these here. */ + break; } -} - -/* This group of functions initializes the exception handling data - structures at the start of the compilation, initializes the data - structures at the start of a function, and saves and restores the - exception handling data structures for the start/end of a nested - function. */ - -/* Toplevel initialization for EH things. */ - -void -init_eh () -{ - first_rethrow_symbol = create_rethrow_ref (0); - final_rethrow = gen_exception_label (); - last_rethrow_symbol = create_rethrow_ref (CODE_LABEL_NUMBER (final_rethrow)); - - ggc_add_rtx_root (&exception_handler_labels, 1); - ggc_add_rtx_root (&eh_return_context, 1); - ggc_add_rtx_root (&eh_return_stack_adjust, 1); - ggc_add_rtx_root (&eh_return_handler, 1); - ggc_add_rtx_root (&first_rethrow_symbol, 1); - ggc_add_rtx_root (&final_rethrow, 1); - ggc_add_rtx_root (&last_rethrow_symbol, 1); - ggc_add_root (&function_eh_regions, 1, sizeof (function_eh_regions), - mark_func_eh_entry); -} - -/* Initialize the per-function EH information. */ - -void -init_eh_for_function () -{ - cfun->eh = (struct eh_status *) xcalloc (1, sizeof (struct eh_status)); - ehqueue = (struct eh_queue *) xcalloc (1, sizeof (struct eh_queue)); - eh_return_context = NULL_RTX; - eh_return_stack_adjust = NULL_RTX; - eh_return_handler = NULL_RTX; -} -void -free_eh_status (f) - struct function *f; -{ - free (f->eh->x_ehqueue); - free (f->eh); - f->eh = NULL; + abort (); } - -/* This section is for the exception handling specific optimization - pass. */ -/* Determine if the given INSN can throw an exception. */ +/* Retrieve a list of labels of exception handlers which can be + reached by a given insn. */ -int -can_throw_internal (insn) +rtx +reachable_handlers (insn) rtx insn; { - if (GET_CODE (insn) == INSN - && GET_CODE (PATTERN (insn)) == SEQUENCE) - insn = XVECEXP (PATTERN (insn), 0, 0); + struct reachable_info info; + struct eh_region *region; + tree type_thrown; + int region_number; - /* Calls can always potentially throw exceptions, unless they have - a REG_EH_REGION note with a value of 0 or less. */ - if (GET_CODE (insn) == CALL_INSN) + if (GET_CODE (insn) == JUMP_INSN + && GET_CODE (PATTERN (insn)) == RESX) + region_number = XINT (PATTERN (insn), 0); + else { rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - if (!note || INTVAL (XEXP (note, 0)) > 0) - return 1; - } - - if (flag_non_call_exceptions) - { - /* If we wanted asynchronous exceptions, then everything but NOTEs - and CODE_LABELs could throw. */ - if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL) - return 1; + if (!note || INTVAL (XEXP (note, 0)) <= 0) + return NULL; + region_number = INTVAL (XEXP (note, 0)); } - return 0; -} + memset (&info, 0, sizeof (info)); -/* Return nonzero if nothing in this function can throw. */ - -int -nothrow_function_p () -{ - rtx insn; + region = cfun->eh->region_array[region_number]; - if (! flag_exceptions) - return 1; + type_thrown = NULL_TREE; + if (region->type == ERT_THROW) + { + type_thrown = region->u.throw.type; + region = region->outer; + } - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (can_throw_internal (insn)) - return 0; - for (insn = current_function_epilogue_delay_list; insn; - insn = XEXP (insn, 1)) - if (can_throw_internal (insn)) - return 0; + for (; region; region = region->outer) + if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT) + break; - return 1; + return info.handlers; } -/* Scan a exception region looking for the matching end and then - remove it if possible. INSN is the start of the region, N is the - region number, and DELETE_OUTER is to note if anything in this - region can throw. - - Regions are removed if they cannot possibly catch an exception. - This is determined by invoking can_throw_internal on each insn within the - region; if can_throw_internal returns true for any of the instructions, the - region can catch an exception, since there is an insn within the - region that is capable of throwing an exception. - - Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or - calls abort if it can't find one. - - Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't - correspond to the region number, or if DELETE_OUTER is NULL. */ +/* Determine if the given INSN can throw an exception that is caught + within the function. */ -static rtx -scan_region (insn, n, delete_outer) +bool +can_throw_internal (insn) rtx insn; - int n; - int *delete_outer; { - rtx start = insn; - - /* Assume we can delete the region. */ - int delete = 1; - - /* Can't delete something which is rethrown from. */ - if (rethrow_used (n)) - delete = 0; + struct eh_region *region; + tree type_thrown; + rtx note; - if (insn == NULL_RTX - || GET_CODE (insn) != NOTE - || NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG - || NOTE_EH_HANDLER (insn) != n - || delete_outer == NULL) - abort (); + if (! INSN_P (insn)) + return false; - insn = NEXT_INSN (insn); + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SEQUENCE) + insn = XVECEXP (PATTERN (insn), 0, 0); - /* Look for the matching end. */ - while (! (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) + if (GET_CODE (insn) == CALL_INSN + && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER) { - /* If anything can throw, we can't remove the region. */ - if (delete && can_throw_internal (insn)) + int i; + for (i = 0; i < 3; ++i) { - delete = 0; + rtx sub = XEXP (PATTERN (insn), i); + for (; sub ; sub = NEXT_INSN (sub)) + if (can_throw_internal (sub)) + return true; } - - /* Watch out for and handle nested regions. */ - if (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - { - insn = scan_region (insn, NOTE_EH_HANDLER (insn), &delete); - } - - insn = NEXT_INSN (insn); + return false; } - /* The _BEG/_END NOTEs must match and nest. */ - if (NOTE_EH_HANDLER (insn) != n) - abort (); - - /* If anything in this exception region can throw, we can throw. */ - if (! delete) - *delete_outer = 0; - else - { - /* Delete the start and end of the region. */ - delete_insn (start); - delete_insn (insn); - -/* We no longer removed labels here, since flow will now remove any - handler which cannot be called any more. */ - -#if 0 - /* Only do this part if we have built the exception handler - labels. */ - if (exception_handler_labels) - { - rtx x, *prev = &exception_handler_labels; + /* Every insn that might throw has an EH_REGION note. */ + note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + if (!note || INTVAL (XEXP (note, 0)) <= 0) + return false; - /* Find it in the list of handlers. */ - for (x = exception_handler_labels; x; x = XEXP (x, 1)) - { - rtx label = XEXP (x, 0); - if (CODE_LABEL_NUMBER (label) == n) - { - /* If we are the last reference to the handler, - delete it. */ - if (--LABEL_NUSES (label) == 0) - delete_insn (label); + region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; - if (optimize) - { - /* Remove it from the list of exception handler - labels, if we are optimizing. If we are not, then - leave it in the list, as we are not really going to - remove the region. */ - *prev = XEXP (x, 1); - XEXP (x, 1) = 0; - XEXP (x, 0) = 0; - } + type_thrown = NULL_TREE; + if (region->type == ERT_THROW) + { + type_thrown = region->u.throw.type; + region = region->outer; + } - break; - } - prev = &XEXP (x, 1); - } - } -#endif + /* If this exception is ignored by each and every containing region, + then control passes straight out. The runtime may handle some + regions, which also do not require processing internally. */ + for (; region; region = region->outer) + { + enum reachable_code how = reachable_next_level (region, type_thrown, 0); + if (how == RNL_BLOCKED) + return false; + if (how != RNL_NOT_CAUGHT) + return true; } - return insn; -} -/* Perform various interesting optimizations for exception handling - code. + return false; +} - We look for empty exception regions and make them go (away). The - jump optimization code will remove the handler if nothing else uses - it. */ +/* Determine if the given INSN can throw an exception that is + visible outside the function. */ -void -exception_optimize () +bool +can_throw_external (insn) + rtx insn; { - rtx insn; - int n; + struct eh_region *region; + tree type_thrown; + rtx note; - /* Remove empty regions. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (! INSN_P (insn)) + return false; + + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SEQUENCE) + insn = XVECEXP (PATTERN (insn), 0, 0); + + if (GET_CODE (insn) == CALL_INSN + && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER) { - if (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) + int i; + for (i = 0; i < 3; ++i) { - /* Since scan_region will return the NOTE_INSN_EH_REGION_END - insn, we will indirectly skip through all the insns - inbetween. We are also guaranteed that the value of insn - returned will be valid, as otherwise scan_region won't - return. */ - insn = scan_region (insn, NOTE_EH_HANDLER (insn), &n); + rtx sub = XEXP (PATTERN (insn), i); + for (; sub ; sub = NEXT_INSN (sub)) + if (can_throw_external (sub)) + return true; } + return false; } + + note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + if (!note) + { + /* Calls (and trapping insns) without notes are outside any + exception handling region in this function. We have to + assume it might throw. Given that the front end and middle + ends mark known NOTHROW functions, this isn't so wildly + inaccurate. */ + return (GET_CODE (insn) == CALL_INSN + || (flag_non_call_exceptions + && may_trap_p (PATTERN (insn)))); + } + if (INTVAL (XEXP (note, 0)) <= 0) + return false; + + region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; + + type_thrown = NULL_TREE; + if (region->type == ERT_THROW) + { + type_thrown = region->u.throw.type; + region = region->outer; + } + + /* If the exception is caught or blocked by any containing region, + then it is not seen by any calling function. */ + for (; region ; region = region->outer) + if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT) + return false; + + return true; } -/* This function determines whether the rethrow labels for any of the - exception regions in the current function are used or not, and set - the reference flag according. */ +/* True if nothing in this function can throw outside this function. */ -void -update_rethrow_references () +bool +nothrow_function_p () { rtx insn; - int x, region; - int *saw_region, *saw_rethrow; - - if (!flag_new_exceptions) - return; - saw_region = (int *) xcalloc (current_func_eh_entry, sizeof (int)); - saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int)); + if (! flag_exceptions) + return true; - /* Determine what regions exist, and whether there are any rethrows - from those regions or not. */ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (GET_CODE (insn) == CALL_INSN) - { - rtx note = find_reg_note (insn, REG_EH_RETHROW, NULL_RTX); - if (note) - { - region = eh_region_from_symbol (XEXP (note, 0)); - region = find_func_region (region); - saw_rethrow[region] = 1; - } - } - else - if (GET_CODE (insn) == NOTE) - { - if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - { - region = find_func_region (NOTE_EH_HANDLER (insn)); - saw_region[region] = 1; - } - } - - /* For any regions we did see, set the referenced flag. */ - for (x = 0; x < current_func_eh_entry; x++) - if (saw_region[x]) - function_eh_regions[x].rethrow_ref = saw_rethrow[x]; + if (can_throw_external (insn)) + return false; + for (insn = current_function_epilogue_delay_list; insn; + insn = XEXP (insn, 1)) + if (can_throw_external (insn)) + return false; - /* Clean up. */ - free (saw_region); - free (saw_rethrow); + return true; } + -/* Various hooks for the DWARF 2 __throw routine. */ +/* Various hooks for unwind library. */ /* Do any necessary initialization to access arbitrary stack frames. On the SPARC, this means flushing the register windows. */ @@ -2950,6 +2882,33 @@ expand_builtin_unwind_init () #endif } +rtx +expand_builtin_eh_return_data_regno (arglist) + tree arglist; +{ + tree which = TREE_VALUE (arglist); + unsigned HOST_WIDE_INT iwhich; + + if (TREE_CODE (which) != INTEGER_CST) + { + error ("argument of `__builtin_eh_return_regno' must be constant"); + return constm1_rtx; + } + + iwhich = tree_low_cst (which, 1); + iwhich = EH_RETURN_DATA_REGNO (iwhich); + if (iwhich == INVALID_REGNUM) + return constm1_rtx; + +#ifdef DWARF_FRAME_REGNUM + iwhich = DWARF_FRAME_REGNUM (iwhich); +#else + iwhich = DBX_REGISTER_NUMBER (iwhich); +#endif + + return GEN_INT (iwhich); +} + /* Given a value extracted from the return address register or stack slot, return the actual address encoded in that value. */ @@ -2958,7 +2917,18 @@ expand_builtin_extract_return_addr (addr_tree) tree addr_tree; { rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0); - return eh_outer_context (addr); + + /* First mask out any unwanted bits. */ +#ifdef MASK_RETURN_ADDR + expand_and (addr, MASK_RETURN_ADDR, addr); +#endif + + /* Then adjust to find the real return address. */ +#if defined (RETURN_ADDR_OFFSET) + addr = plus_constant (addr, RETURN_ADDR_OFFSET); +#endif + + return addr; } /* Given an actual address in addr_tree, do any necessary encoding @@ -2970,540 +2940,773 @@ expand_builtin_frob_return_addr (addr_tree) tree addr_tree; { rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0); + #ifdef RETURN_ADDR_OFFSET + addr = force_reg (Pmode, addr); addr = plus_constant (addr, -RETURN_ADDR_OFFSET); #endif + return addr; } -/* Choose three registers for communication between the main body of - __throw and the epilogue (or eh stub) and the exception handler. - We must do this with hard registers because the epilogue itself - will be generated after reload, at which point we may not reference - pseudos at all. - - The first passes the exception context to the handler. For this - we use the return value register for a void*. - - The second holds the stack pointer value to be restored. For this - we use the static chain register if it exists, is different from - the previous, and is call-clobbered; otherwise some arbitrary - call-clobbered register. - - The third holds the address of the handler itself. Here we use - some arbitrary call-clobbered register. */ +/* Set up the epilogue with the magic bits we'll need to return to the + exception handler. */ -static void -eh_regs (pcontext, psp, pra, outgoing) - rtx *pcontext, *psp, *pra; - int outgoing ATTRIBUTE_UNUSED; +void +expand_builtin_eh_return (stackadj_tree, handler_tree) + tree stackadj_tree, handler_tree; { - rtx rcontext, rsp, rra; - unsigned int i; - tree t; + rtx stackadj, handler; - t = build_pointer_type (void_type_node); -#ifdef FUNCTION_OUTGOING_VALUE - if (outgoing) - rcontext = FUNCTION_OUTGOING_VALUE (t, current_function_decl); - else -#endif - rcontext = FUNCTION_VALUE (t, current_function_decl); + stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0); + handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0); -#ifdef STATIC_CHAIN_REGNUM - if (outgoing) - rsp = static_chain_incoming_rtx; + if (! cfun->eh->ehr_label) + { + cfun->eh->ehr_stackadj = copy_to_reg (stackadj); + cfun->eh->ehr_handler = copy_to_reg (handler); + cfun->eh->ehr_label = gen_label_rtx (); + } else - rsp = static_chain_rtx; - if (REGNO (rsp) == REGNO (rcontext) - || ! call_used_regs [REGNO (rsp)]) -#endif /* STATIC_CHAIN_REGNUM */ - rsp = NULL_RTX; - - if (rsp == NULL_RTX) { - for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) - if (call_used_regs[i] && ! fixed_regs[i] && i != REGNO (rcontext)) - break; - if (i == FIRST_PSEUDO_REGISTER) - abort(); - - rsp = gen_rtx_REG (Pmode, i); + if (stackadj != cfun->eh->ehr_stackadj) + emit_move_insn (cfun->eh->ehr_stackadj, stackadj); + if (handler != cfun->eh->ehr_handler) + emit_move_insn (cfun->eh->ehr_handler, handler); } - for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) - if (call_used_regs[i] && ! fixed_regs[i] - && i != REGNO (rcontext) && i != REGNO (rsp)) - break; - if (i == FIRST_PSEUDO_REGISTER) - abort(); - - rra = gen_rtx_REG (Pmode, i); - - *pcontext = rcontext; - *psp = rsp; - *pra = rra; -} - -/* Retrieve the register which contains the pointer to the eh_context - structure set the __throw. */ - -#if 0 -rtx -get_reg_for_handler () -{ - rtx reg1; - reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node), - current_function_decl); - return reg1; -} -#endif - -/* Set up the epilogue with the magic bits we'll need to return to the - exception handler. */ - -void -expand_builtin_eh_return (context, stack, handler) - tree context, stack, handler; -{ - if (eh_return_context) - error("Duplicate call to __builtin_eh_return"); - - eh_return_context - = copy_to_reg (expand_expr (context, NULL_RTX, VOIDmode, 0)); - eh_return_stack_adjust - = copy_to_reg (expand_expr (stack, NULL_RTX, VOIDmode, 0)); - eh_return_handler - = copy_to_reg (expand_expr (handler, NULL_RTX, VOIDmode, 0)); + emit_jump (cfun->eh->ehr_label); } void expand_eh_return () { - rtx reg1, reg2, reg3; - rtx stub_start, after_stub; - rtx ra, tmp; + rtx sa, ra, around_label; - if (!eh_return_context) + if (! cfun->eh->ehr_label) return; - current_function_cannot_inline = N_("function uses __builtin_eh_return"); - - eh_regs (®1, ®2, ®3, 1); -#ifdef POINTERS_EXTEND_UNSIGNED - eh_return_context = convert_memory_address (Pmode, eh_return_context); - eh_return_stack_adjust = - convert_memory_address (Pmode, eh_return_stack_adjust); - eh_return_handler = convert_memory_address (Pmode, eh_return_handler); -#endif - emit_move_insn (reg1, eh_return_context); - emit_move_insn (reg2, eh_return_stack_adjust); - emit_move_insn (reg3, eh_return_handler); - - /* Talk directly to the target's epilogue code when possible. */ - -#ifdef HAVE_eh_epilogue - if (HAVE_eh_epilogue) + sa = EH_RETURN_STACKADJ_RTX; + if (! sa) { - emit_insn (gen_eh_epilogue (reg1, reg2, reg3)); + error ("__builtin_eh_return not supported on this target"); return; } -#endif - - /* Otherwise, use the same stub technique we had before. */ - eh_return_stub_label = stub_start = gen_label_rtx (); - after_stub = gen_label_rtx (); + current_function_calls_eh_return = 1; - /* Set the return address to the stub label. */ + around_label = gen_label_rtx (); + emit_move_insn (sa, const0_rtx); + emit_jump (around_label); - ra = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, - 0, hard_frame_pointer_rtx); - if (GET_CODE (ra) == REG && REGNO (ra) >= FIRST_PSEUDO_REGISTER) - abort(); + emit_label (cfun->eh->ehr_label); + clobber_return_register (); - tmp = memory_address (Pmode, gen_rtx_LABEL_REF (Pmode, stub_start)); -#ifdef RETURN_ADDR_OFFSET - tmp = plus_constant (tmp, -RETURN_ADDR_OFFSET); +#ifdef HAVE_eh_return + if (HAVE_eh_return) + emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, cfun->eh->ehr_handler)); + else #endif - tmp = force_operand (tmp, ra); - if (tmp != ra) - emit_move_insn (ra, tmp); - - /* Indicate that the registers are in fact used. */ - emit_insn (gen_rtx_USE (VOIDmode, reg1)); - emit_insn (gen_rtx_USE (VOIDmode, reg2)); - emit_insn (gen_rtx_USE (VOIDmode, reg3)); - if (GET_CODE (ra) == REG) - emit_insn (gen_rtx_USE (VOIDmode, ra)); - - /* Generate the stub. */ - - emit_jump (after_stub); - emit_label (stub_start); + { + ra = EH_RETURN_HANDLER_RTX; + if (! ra) + { + error ("__builtin_eh_return not supported on this target"); + ra = gen_reg_rtx (Pmode); + } - eh_regs (®1, ®2, ®3, 0); - adjust_stack (reg2); - emit_indirect_jump (reg3); + emit_move_insn (sa, cfun->eh->ehr_stackadj); + emit_move_insn (ra, cfun->eh->ehr_handler); + } - emit_label (after_stub); + emit_label (around_label); } +struct action_record +{ + int offset; + int filter; + int next; +}; -/* This contains the code required to verify whether arbitrary instructions - are in the same exception region. */ +static int +action_record_eq (pentry, pdata) + const PTR pentry; + const PTR pdata; +{ + const struct action_record *entry = (const struct action_record *) pentry; + const struct action_record *data = (const struct action_record *) pdata; + return entry->filter == data->filter && entry->next == data->next; +} -static int *insn_eh_region = (int *)0; -static int maximum_uid; +static hashval_t +action_record_hash (pentry) + const PTR pentry; +{ + const struct action_record *entry = (const struct action_record *) pentry; + return entry->next * 1009 + entry->filter; +} -static void -set_insn_eh_region (first, region_num) - rtx *first; - int region_num; +static int +add_action_record (ar_hash, filter, next) + htab_t ar_hash; + int filter, next; { - rtx insn; - int rnum; + struct action_record **slot, *new, tmp; + + tmp.filter = filter; + tmp.next = next; + slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT); - for (insn = *first; insn; insn = NEXT_INSN (insn)) + if ((new = *slot) == NULL) { - if ((GET_CODE (insn) == NOTE) - && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)) - { - rnum = NOTE_EH_HANDLER (insn); - insn_eh_region[INSN_UID (insn)] = rnum; - insn = NEXT_INSN (insn); - set_insn_eh_region (&insn, rnum); - /* Upon return, insn points to the EH_REGION_END of nested region */ - continue; - } - insn_eh_region[INSN_UID (insn)] = region_num; - if ((GET_CODE (insn) == NOTE) && - (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) - break; + new = (struct action_record *) xmalloc (sizeof (*new)); + new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1; + new->filter = filter; + new->next = next; + *slot = new; + + /* The filter value goes in untouched. The link to the next + record is a "self-relative" byte offset, or zero to indicate + that there is no next record. So convert the absolute 1 based + indicies we've been carrying around into a displacement. */ + + push_sleb128 (&cfun->eh->action_record_data, filter); + if (next) + next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1; + push_sleb128 (&cfun->eh->action_record_data, next); } - *first = insn; -} -/* Free the insn table, an make sure it cannot be used again. */ + return new->offset; +} -void -free_insn_eh_region () +static int +collect_one_action_chain (ar_hash, region) + htab_t ar_hash; + struct eh_region *region; { - if (!doing_eh (0)) - return; + struct eh_region *c; + int next; - if (insn_eh_region) + /* If we've reached the top of the region chain, then we have + no actions, and require no landing pad. */ + if (region == NULL) + return -1; + + switch (region->type) { - free (insn_eh_region); - insn_eh_region = (int *)0; + case ERT_CLEANUP: + /* A cleanup adds a zero filter to the beginning of the chain, but + there are special cases to look out for. If there are *only* + cleanups along a path, then it compresses to a zero action. + Further, if there are multiple cleanups along a path, we only + need to represent one of them, as that is enough to trigger + entry to the landing pad at runtime. */ + next = collect_one_action_chain (ar_hash, region->outer); + if (next <= 0) + return 0; + for (c = region->outer; c ; c = c->outer) + if (c->type == ERT_CLEANUP) + return next; + return add_action_record (ar_hash, 0, next); + + case ERT_TRY: + /* Process the associated catch regions in reverse order. + If there's a catch-all handler, then we don't need to + search outer regions. Use a magic -3 value to record + that we havn't done the outer search. */ + next = -3; + for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch) + { + if (c->u.catch.type == NULL) + next = add_action_record (ar_hash, c->u.catch.filter, 0); + else + { + if (next == -3) + { + next = collect_one_action_chain (ar_hash, region->outer); + if (next < 0) + next = 0; + } + next = add_action_record (ar_hash, c->u.catch.filter, next); + } + } + return next; + + case ERT_ALLOWED_EXCEPTIONS: + /* An exception specification adds its filter to the + beginning of the chain. */ + next = collect_one_action_chain (ar_hash, region->outer); + return add_action_record (ar_hash, region->u.allowed.filter, + next < 0 ? 0 : next); + + case ERT_MUST_NOT_THROW: + /* A must-not-throw region with no inner handlers or cleanups + requires no call-site entry. Note that this differs from + the no handler or cleanup case in that we do require an lsda + to be generated. Return a magic -2 value to record this. */ + return -2; + + case ERT_CATCH: + case ERT_THROW: + /* CATCH regions are handled in TRY above. THROW regions are + for optimization information only and produce no output. */ + return collect_one_action_chain (ar_hash, region->outer); + + default: + abort (); } } -/* Initialize the table. max_uid must be calculated and handed into - this routine. If it is unavailable, passing a value of 0 will - cause this routine to calculate it as well. */ - -void -init_insn_eh_region (first, max_uid) - rtx first; - int max_uid; +static int +add_call_site (landing_pad, action) + rtx landing_pad; + int action; { - rtx insn; + struct call_site_record *data = cfun->eh->call_site_data; + int used = cfun->eh->call_site_data_used; + int size = cfun->eh->call_site_data_size; - if (!doing_eh (0)) - return; + if (used >= size) + { + size = (size ? size * 2 : 64); + data = (struct call_site_record *) + xrealloc (data, sizeof (*data) * size); + cfun->eh->call_site_data = data; + cfun->eh->call_site_data_size = size; + } - if (insn_eh_region) - free_insn_eh_region(); + data[used].landing_pad = landing_pad; + data[used].action = action; - if (max_uid == 0) - for (insn = first; insn; insn = NEXT_INSN (insn)) - if (INSN_UID (insn) > max_uid) /* find largest UID */ - max_uid = INSN_UID (insn); + cfun->eh->call_site_data_used = used + 1; - maximum_uid = max_uid; - insn_eh_region = (int *) xmalloc ((max_uid + 1) * sizeof (int)); - insn = first; - set_insn_eh_region (&insn, 0); + return used + call_site_base; } +/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes. + The new note numbers will not refer to region numbers, but + instead to call site entries. */ -/* Check whether 2 instructions are within the same region. */ - -int -in_same_eh_region (insn1, insn2) - rtx insn1, insn2; +void +convert_to_eh_region_ranges () { - int ret, uid1, uid2; + rtx insn, iter, note; + htab_t ar_hash; + int last_action = -3; + rtx last_action_insn = NULL_RTX; + rtx last_landing_pad = NULL_RTX; + rtx first_no_action_insn = NULL_RTX; + int call_site; - /* If no exceptions, instructions are always in same region. */ - if (!doing_eh (0)) - return 1; + if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL) + return; - /* If the table isn't allocated, assume the worst. */ - if (!insn_eh_region) - return 0; + VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data"); - uid1 = INSN_UID (insn1); - uid2 = INSN_UID (insn2); + ar_hash = htab_create (31, action_record_hash, action_record_eq, free); - /* if instructions have been allocated beyond the end, either - the table is out of date, or this is a late addition, or - something... Assume the worst. */ - if (uid1 > maximum_uid || uid2 > maximum_uid) - return 0; + for (iter = get_insns (); iter ; iter = NEXT_INSN (iter)) + if (INSN_P (iter)) + { + struct eh_region *region; + int this_action; + rtx this_landing_pad; - ret = (insn_eh_region[uid1] == insn_eh_region[uid2]); - return ret; -} - + insn = iter; + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SEQUENCE) + insn = XVECEXP (PATTERN (insn), 0, 0); -/* This function will initialize the handler list for a specified block. - It may recursively call itself if the outer block hasn't been processed - yet. At some point in the future we can trim out handlers which we - know cannot be called. (ie, if a block has an INT type handler, - control will never be passed to an outer INT type handler). */ - -static void -process_nestinfo (block, info, nested_eh_region) - int block; - eh_nesting_info *info; - int *nested_eh_region; -{ - handler_info *ptr, *last_ptr = NULL; - int x, y, count = 0; - int extra = 0; - handler_info **extra_handlers = 0; - int index = info->region_index[block]; - - /* If we've already processed this block, simply return. */ - if (info->num_handlers[index] > 0) - return; + note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + if (!note) + { + if (! (GET_CODE (insn) == CALL_INSN + || (flag_non_call_exceptions + && may_trap_p (PATTERN (insn))))) + continue; + this_action = -1; + region = NULL; + } + else + { + if (INTVAL (XEXP (note, 0)) <= 0) + continue; + region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; + this_action = collect_one_action_chain (ar_hash, region); + } + + /* Existence of catch handlers, or must-not-throw regions + implies that an lsda is needed (even if empty). */ + if (this_action != -1) + cfun->uses_eh_lsda = 1; + + /* Delay creation of region notes for no-action regions + until we're sure that an lsda will be required. */ + else if (last_action == -3) + { + first_no_action_insn = iter; + last_action = -1; + } - for (ptr = get_first_handler (block); ptr; last_ptr = ptr, ptr = ptr->next) - count++; + /* Cleanups and handlers may share action chains but not + landing pads. Collect the landing pad for this region. */ + if (this_action >= 0) + { + struct eh_region *o; + for (o = region; ! o->landing_pad ; o = o->outer) + continue; + this_landing_pad = o->landing_pad; + } + else + this_landing_pad = NULL_RTX; - /* pick up any information from the next outer region. It will already - contain a summary of itself and all outer regions to it. */ + /* Differing actions or landing pads implies a change in call-site + info, which implies some EH_REGION note should be emitted. */ + if (last_action != this_action + || last_landing_pad != this_landing_pad) + { + /* If we'd not seen a previous action (-3) or the previous + action was must-not-throw (-2), then we do not need an + end note. */ + if (last_action >= -1) + { + /* If we delayed the creation of the begin, do it now. */ + if (first_no_action_insn) + { + call_site = add_call_site (NULL_RTX, 0); + note = emit_note_before (NOTE_INSN_EH_REGION_BEG, + first_no_action_insn); + NOTE_EH_HANDLER (note) = call_site; + first_no_action_insn = NULL_RTX; + } + + note = emit_note_after (NOTE_INSN_EH_REGION_END, + last_action_insn); + NOTE_EH_HANDLER (note) = call_site; + } + + /* If the new action is must-not-throw, then no region notes + are created. */ + if (this_action >= -1) + { + call_site = add_call_site (this_landing_pad, + this_action < 0 ? 0 : this_action); + note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter); + NOTE_EH_HANDLER (note) = call_site; + } + + last_action = this_action; + last_landing_pad = this_landing_pad; + } + last_action_insn = iter; + } - if (nested_eh_region [block] != 0) + if (last_action >= -1 && ! first_no_action_insn) { - int nested_index = info->region_index[nested_eh_region[block]]; - process_nestinfo (nested_eh_region[block], info, nested_eh_region); - extra = info->num_handlers[nested_index]; - extra_handlers = info->handlers[nested_index]; - info->outer_index[index] = nested_index; + note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn); + NOTE_EH_HANDLER (note) = call_site; } - /* If the last handler is either a CATCH_ALL or a cleanup, then we - won't use the outer ones since we know control will not go past the - catch-all or cleanup. */ + htab_delete (ar_hash); +} - if (last_ptr != NULL && (last_ptr->type_info == NULL - || last_ptr->type_info == CATCH_ALL_TYPE)) - extra = 0; + +static void +push_uleb128 (data_area, value) + varray_type *data_area; + unsigned int value; +{ + do + { + unsigned char byte = value & 0x7f; + value >>= 7; + if (value) + byte |= 0x80; + VARRAY_PUSH_UCHAR (*data_area, byte); + } + while (value); +} - info->num_handlers[index] = count + extra; - info->handlers[index] = (handler_info **) xmalloc ((count + extra) - * sizeof (handler_info **)); +static void +push_sleb128 (data_area, value) + varray_type *data_area; + int value; +{ + unsigned char byte; + int more; - /* First put all our handlers into the list. */ - ptr = get_first_handler (block); - for (x = 0; x < count; x++) + do { - info->handlers[index][x] = ptr; - ptr = ptr->next; + byte = value & 0x7f; + value >>= 7; + more = ! ((value == 0 && (byte & 0x40) == 0) + || (value == -1 && (byte & 0x40) != 0)); + if (more) + byte |= 0x80; + VARRAY_PUSH_UCHAR (*data_area, byte); } + while (more); +} - /* Now add all the outer region handlers, if they aren't they same as - one of the types in the current block. We won't worry about - derived types yet, we'll just look for the exact type. */ - for (y =0, x = 0; x < extra ; x++) + +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 + +static const char * +eh_data_format_name (format) + int format; +{ + switch (format) { - int i, ok; - ok = 1; - /* Check to see if we have a type duplication. */ - for (i = 0; i < count; i++) - if (info->handlers[index][i]->type_info == extra_handlers[x]->type_info) - { - ok = 0; - /* Record one less handler. */ - (info->num_handlers[index])--; - break; - } - if (ok) - { - info->handlers[index][y + count] = extra_handlers[x]; - y++; - } + case DW_EH_PE_absptr: return "absolute"; + case DW_EH_PE_omit: return "omit"; + + case DW_EH_PE_uleb128: return "uleb128"; + case DW_EH_PE_udata2: return "udata2"; + case DW_EH_PE_udata4: return "udata4"; + case DW_EH_PE_udata8: return "udata8"; + case DW_EH_PE_sleb128: return "sleb128"; + case DW_EH_PE_sdata2: return "sdata2"; + case DW_EH_PE_sdata4: return "sdata4"; + case DW_EH_PE_sdata8: return "sdata8"; + + case DW_EH_PE_uleb128 | DW_EH_PE_pcrel: return "pcrel uleb128"; + case DW_EH_PE_udata2 | DW_EH_PE_pcrel: return "pcrel udata2"; + case DW_EH_PE_udata4 | DW_EH_PE_pcrel: return "pcrel udata4"; + case DW_EH_PE_udata8 | DW_EH_PE_pcrel: return "pcrel udata8"; + case DW_EH_PE_sleb128 | DW_EH_PE_pcrel: return "pcrel sleb128"; + case DW_EH_PE_sdata2 | DW_EH_PE_pcrel: return "pcrel sdata2"; + case DW_EH_PE_sdata4 | DW_EH_PE_pcrel: return "pcrel sdata4"; + case DW_EH_PE_sdata8 | DW_EH_PE_pcrel: return "pcrel sdata8"; + + case DW_EH_PE_uleb128 | DW_EH_PE_textrel: return "textrel uleb128"; + case DW_EH_PE_udata2 | DW_EH_PE_textrel: return "textrel udata2"; + case DW_EH_PE_udata4 | DW_EH_PE_textrel: return "textrel udata4"; + case DW_EH_PE_udata8 | DW_EH_PE_textrel: return "textrel udata8"; + case DW_EH_PE_sleb128 | DW_EH_PE_textrel: return "textrel sleb128"; + case DW_EH_PE_sdata2 | DW_EH_PE_textrel: return "textrel sdata2"; + case DW_EH_PE_sdata4 | DW_EH_PE_textrel: return "textrel sdata4"; + case DW_EH_PE_sdata8 | DW_EH_PE_textrel: return "textrel sdata8"; + + case DW_EH_PE_uleb128 | DW_EH_PE_datarel: return "datarel uleb128"; + case DW_EH_PE_udata2 | DW_EH_PE_datarel: return "datarel udata2"; + case DW_EH_PE_udata4 | DW_EH_PE_datarel: return "datarel udata4"; + case DW_EH_PE_udata8 | DW_EH_PE_datarel: return "datarel udata8"; + case DW_EH_PE_sleb128 | DW_EH_PE_datarel: return "datarel sleb128"; + case DW_EH_PE_sdata2 | DW_EH_PE_datarel: return "datarel sdata2"; + case DW_EH_PE_sdata4 | DW_EH_PE_datarel: return "datarel sdata4"; + case DW_EH_PE_sdata8 | DW_EH_PE_datarel: return "datarel sdata8"; + + case DW_EH_PE_uleb128 | DW_EH_PE_funcrel: return "funcrel uleb128"; + case DW_EH_PE_udata2 | DW_EH_PE_funcrel: return "funcrel udata2"; + case DW_EH_PE_udata4 | DW_EH_PE_funcrel: return "funcrel udata4"; + case DW_EH_PE_udata8 | DW_EH_PE_funcrel: return "funcrel udata8"; + case DW_EH_PE_sleb128 | DW_EH_PE_funcrel: return "funcrel sleb128"; + case DW_EH_PE_sdata2 | DW_EH_PE_funcrel: return "funcrel sdata2"; + case DW_EH_PE_sdata4 | DW_EH_PE_funcrel: return "funcrel sdata4"; + case DW_EH_PE_sdata8 | DW_EH_PE_funcrel: return "funcrel sdata8"; + + default: + abort (); } } -/* This function will allocate and initialize an eh_nesting_info structure. - It returns a pointer to the completed data structure. If there are - no exception regions, a NULL value is returned. */ - -eh_nesting_info * -init_eh_nesting_info () +#ifndef HAVE_AS_LEB128 +static int +dw2_size_of_call_site_table () { - int *nested_eh_region; - int region_count = 0; - rtx eh_note = NULL_RTX; - eh_nesting_info *info; - rtx insn; - int x; + int n = cfun->eh->call_site_data_used; + int size = n * (4 + 4 + 4); + int i; - if (! flag_exceptions) - return 0; + for (i = 0; i < n; ++i) + { + struct call_site_record *cs = &cfun->eh->call_site_data[i]; + size += size_of_uleb128 (cs->action); + } - info = (eh_nesting_info *) xmalloc (sizeof (eh_nesting_info)); - info->region_index = (int *) xcalloc ((max_label_num () + 1), sizeof (int)); - nested_eh_region = (int *) xcalloc (max_label_num () + 1, sizeof (int)); + return size; +} + +static int +sjlj_size_of_call_site_table () +{ + int n = cfun->eh->call_site_data_used; + int size = 0; + int i; - /* Create the nested_eh_region list. If indexed with a block number, it - returns the block number of the next outermost region, if any. - We can count the number of regions and initialize the region_index - vector at the same time. */ - for (insn = get_insns(); insn; insn = NEXT_INSN (insn)) + for (i = 0; i < n; ++i) { - if (GET_CODE (insn) == NOTE) - { - if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - { - int block = NOTE_EH_HANDLER (insn); - region_count++; - info->region_index[block] = region_count; - if (eh_note) - nested_eh_region [block] = - NOTE_EH_HANDLER (XEXP (eh_note, 0)); - else - nested_eh_region [block] = 0; - eh_note = gen_rtx_EXPR_LIST (VOIDmode, insn, eh_note); - } - else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END) - eh_note = XEXP (eh_note, 1); - } + struct call_site_record *cs = &cfun->eh->call_site_data[i]; + size += size_of_uleb128 (INTVAL (cs->landing_pad)); + size += size_of_uleb128 (cs->action); } - - /* If there are no regions, wrap it up now. */ - if (region_count == 0) + + return size; +} +#endif + +static void +dw2_output_call_site_table () +{ + const char *function_start_lab + = IDENTIFIER_POINTER (current_function_func_begin_label); + int n = cfun->eh->call_site_data_used; + int i; + + for (i = 0; i < n; ++i) { - free (info->region_index); - free (info); - free (nested_eh_region); - return NULL; + struct call_site_record *cs = &cfun->eh->call_site_data[i]; + char reg_start_lab[32]; + char reg_end_lab[32]; + char landing_pad_lab[32]; + + ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i); + ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i); + + if (cs->landing_pad) + ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L", + CODE_LABEL_NUMBER (cs->landing_pad)); + + /* ??? Perhaps use insn length scaling if the assembler supports + generic arithmetic. */ + /* ??? Perhaps use attr_length to choose data1 or data2 instead of + data4 if the function is small enough. */ +#ifdef HAVE_AS_LEB128 + dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab, + "region %d start", i); + dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab, + "length"); + if (cs->landing_pad) + dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab, + "landing pad"); + else + dw2_asm_output_data_uleb128 (0, "landing pad"); +#else + dw2_asm_output_delta (4, reg_start_lab, function_start_lab, + "region %d start", i); + dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length"); + if (cs->landing_pad) + dw2_asm_output_delta (4, landing_pad_lab, function_start_lab, + "landing pad"); + else + dw2_asm_output_data (4, 0, "landing pad"); +#endif + dw2_asm_output_data_uleb128 (cs->action, "action"); } - region_count++; - info->handlers = (handler_info ***) xcalloc (region_count, - sizeof (handler_info ***)); - info->num_handlers = (int *) xcalloc (region_count, sizeof (int)); - info->outer_index = (int *) xcalloc (region_count, sizeof (int)); + call_site_base += n; +} + +static void +sjlj_output_call_site_table () +{ + int n = cfun->eh->call_site_data_used; + int i; - /* Now initialize the handler lists for all exception blocks. */ - for (x = 0; x <= max_label_num (); x++) + for (i = 0; i < n; ++i) { - if (info->region_index[x] != 0) - process_nestinfo (x, info, nested_eh_region); - } - info->region_count = region_count; + struct call_site_record *cs = &cfun->eh->call_site_data[i]; - /* Clean up. */ - free (nested_eh_region); + dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad), + "region %d landing pad", i); + dw2_asm_output_data_uleb128 (cs->action, "action"); + } - return info; + call_site_base += n; } +void +output_function_exception_table () +{ + int format, i, n; +#ifdef HAVE_AS_LEB128 + char ttype_label[32]; + char cs_after_size_label[32]; + char cs_end_label[32]; +#else + int call_site_len; +#endif + int have_tt_data; + int funcdef_number; -/* This function is used to retreive the vector of handlers which - can be reached by a given insn in a given exception region. - BLOCK is the exception block the insn is in. - INFO is the eh_nesting_info structure. - INSN is the (optional) insn within the block. If insn is not NULL_RTX, - it may contain reg notes which modify its throwing behavior, and - these will be obeyed. If NULL_RTX is passed, then we simply return the - handlers for block. - HANDLERS is the address of a pointer to a vector of handler_info pointers. - Upon return, this will have the handlers which can be reached by block. - This function returns the number of elements in the handlers vector. */ + /* Not all functions need anything. */ + if (! cfun->uses_eh_lsda) + return; -int -reachable_handlers (block, info, insn, handlers) - int block; - eh_nesting_info *info; - rtx insn ; - handler_info ***handlers; -{ - int index = 0; - *handlers = NULL; + funcdef_number = (USING_SJLJ_EXCEPTIONS + ? sjlj_funcdef_number + : current_funcdef_number); - if (info == NULL) - return 0; - if (block > 0) - index = info->region_index[block]; - - if (insn && GET_CODE (insn) == CALL_INSN) - { - /* RETHROWs specify a region number from which we are going to rethrow. - This means we won't pass control to handlers in the specified - region, but rather any region OUTSIDE the specified region. - We accomplish this by setting block to the outer_index of the - specified region. */ - rtx note = find_reg_note (insn, REG_EH_RETHROW, NULL_RTX); - if (note) + exception_section (); + + have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0 + || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0); + + if (have_tt_data) + assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode)); + + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LLSDA", funcdef_number); + + /* The LSDA header. */ + + /* Indicate the format of the landing pad start pointer. An omitted + field implies @LPStart == @Start. */ + /* Currently we always put @LPStart == @Start. This field would + be most useful in moving the landing pads completely out of + line to another section, but it could also be used to minimize + the size of uleb128 landing pad offsets. */ + format = DW_EH_PE_omit; + dw2_asm_output_data (1, format, "@LPStart format (%s)", + eh_data_format_name (format)); + + /* @LPStart pointer would go here. */ + + /* Indicate the format of the @TType entries. */ + if (! have_tt_data) + format = DW_EH_PE_omit; + else + { + /* ??? Define a ASM_PREFERRED_DATA_FORMAT to say what + sort of dynamic-relocation-free reference to emit. */ + format = 0; +#ifdef HAVE_AS_LEB128 + ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", funcdef_number); +#endif + } + dw2_asm_output_data (1, format, "@TType format (%s)", + eh_data_format_name (format)); + +#ifndef HAVE_AS_LEB128 + if (USING_SJLJ_EXCEPTIONS) + call_site_len = sjlj_size_of_call_site_table (); + else + call_site_len = dw2_size_of_call_site_table (); +#endif + + /* A pc-relative 4-byte displacement to the @TType data. */ + if (have_tt_data) + { +#ifdef HAVE_AS_LEB128 + char ttype_after_disp_label[32]; + ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD", + funcdef_number); + dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label, + "@TType base offset"); + ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label); +#else + /* Ug. Alignment queers things. */ + unsigned int before_disp, after_disp, last_disp, disp, align; + + align = POINTER_SIZE / BITS_PER_UNIT; + before_disp = 1 + 1; + after_disp = (1 + size_of_uleb128 (call_site_len) + + call_site_len + + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + + VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) * align); + + disp = after_disp; + do { - index = eh_region_from_symbol (XEXP (note, 0)); - index = info->region_index[index]; - if (index) - index = info->outer_index[index]; - } - else - { - /* If there is no rethrow, we look for a REG_EH_REGION, and - we'll throw from that block. A value of 0 or less - indicates that this insn cannot throw. */ - note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - if (note) - { - int b = INTVAL (XEXP (note, 0)); - if (b <= 0) - index = 0; - else - index = info->region_index[b]; - } + unsigned int disp_size, pad; + + last_disp = disp; + disp_size = size_of_uleb128 (disp); + pad = before_disp + disp_size + after_disp; + if (pad % align) + pad = align - (pad % align); + else + pad = 0; + disp = after_disp + pad; } + while (disp != last_disp); + + dw2_asm_output_data_uleb128 (disp, "@TType base offset"); +#endif } - /* If we reach this point, and index is 0, there is no throw. */ - if (index == 0) - return 0; - - *handlers = info->handlers[index]; - return info->num_handlers[index]; -} + /* Indicate the format of the call-site offsets. */ +#ifdef HAVE_AS_LEB128 + format = DW_EH_PE_uleb128; +#else + format = DW_EH_PE_udata4; +#endif + dw2_asm_output_data (1, format, "call-site format (%s)", + eh_data_format_name (format)); + +#ifdef HAVE_AS_LEB128 + ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB", + funcdef_number); + ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE", + funcdef_number); + dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label, + "Call-site table length"); + ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label); + if (USING_SJLJ_EXCEPTIONS) + sjlj_output_call_site_table (); + else + dw2_output_call_site_table (); + ASM_OUTPUT_LABEL (asm_out_file, cs_end_label); +#else + dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length"); + if (USING_SJLJ_EXCEPTIONS) + sjlj_output_call_site_table (); + else + dw2_output_call_site_table (); +#endif + + /* ??? Decode and interpret the data for flag_debug_asm. */ + n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data); + for (i = 0; i < n; ++i) + dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i), + (i ? NULL : "Action record table")); -/* This function will free all memory associated with the eh_nesting info. */ + if (have_tt_data) + assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode)); -void -free_eh_nesting_info (info) - eh_nesting_info *info; -{ - int x; - if (info != NULL) + i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data); + while (i-- > 0) { - if (info->region_index) - free (info->region_index); - if (info->num_handlers) - free (info->num_handlers); - if (info->outer_index) - free (info->outer_index); - if (info->handlers) - { - for (x = 0; x < info->region_count; x++) - if (info->handlers[x]) - free (info->handlers[x]); - free (info->handlers); - } - free (info); + tree type = VARRAY_TREE (cfun->eh->ttype_data, i); + + if (type == NULL_TREE) + type = integer_zero_node; + else + type = lookup_type_for_runtime (type); + + /* ??? Handle ASM_PREFERRED_DATA_FORMAT. */ + output_constant (type, GET_MODE_SIZE (ptr_mode)); } + +#ifdef HAVE_AS_LEB128 + if (have_tt_data) + ASM_OUTPUT_LABEL (asm_out_file, ttype_label); +#endif + + /* ??? Decode and interpret the data for flag_debug_asm. */ + n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data); + for (i = 0; i < n; ++i) + dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i), + (i ? NULL : "Exception specification table")); + + function_section (current_function_decl); + + if (USING_SJLJ_EXCEPTIONS) + sjlj_funcdef_number += 1; } diff --git a/gcc/except.h b/gcc/except.h index 2b281bbe5f6..d1688a22cb9 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -19,516 +19,187 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if !defined(NULL_RTX) && !defined(rtx) -typedef struct rtx_def *_except_rtx; -#define rtx _except_rtx -#endif - -#ifdef TREE_CODE - -/* A stack of labels. CHAIN points to the next entry in the stack. */ - -struct label_node { - union { - rtx rlabel; - tree tlabel; - } u; - struct label_node *chain; -}; - -/* An eh_entry is used to describe one exception handling region. - - OUTER_CONTEXT is the label used for rethrowing into the outer context. - - EXCEPTION_HANDLER_LABEL is the label corresponding to the handler - for this region. - - LABEL_USED indicates whether a CATCH block has already used this - label or not. New ones are needed for additional catch blocks if - it has. - FALSE_LABEL is used when either setjmp/longjmp exceptions are in - use, or old style table exceptions. It contains the label for - branching to the next runtime type check as handlers are processed. - - FINALIZATION is the tree codes for the handler, or is NULL_TREE if - one hasn't been generated yet, or is integer_zero_node to mark the - end of a group of try blocks. */ - -struct eh_entry { - rtx outer_context; - rtx exception_handler_label; - tree finalization; - int label_used; - rtx false_label; - rtx rethrow_label; - /* If non-zero, this entry is for a handler created when we left an - exception-region via goto. */ - unsigned goto_entry_p : 1; -}; -#else -struct label_node; -struct eh_entry; +#ifndef TREE_CODE +union tree_node; +#define tree union tree_node * #endif -/* A list of EH_ENTRYs. ENTRY is the entry; CHAIN points to the next - entry in the list, or is NULL if this is the last entry. */ - -struct eh_node { - struct eh_entry *entry; - struct eh_node *chain; -}; - -/* A stack of EH_ENTRYs. TOP is the topmost entry on the stack. TOP is - NULL if the stack is empty. */ - -struct eh_stack { - struct eh_node *top; -}; - -/* A queue of EH_ENTRYs. HEAD is the front of the queue; TAIL is the - end (the latest entry). HEAD and TAIL are NULL if the queue is - empty. */ - -struct eh_queue { - struct eh_node *head; - struct eh_node *tail; - struct eh_queue *next; -}; - -/* Used to save exception handling status for each function. */ -struct eh_status -{ - /* A stack used for keeping track of the currently active exception - handling region. As each exception region is started, an entry - describing the region is pushed onto this stack. The current - region can be found by looking at the top of the stack, and as we - exit regions, the corresponding entries are popped. - - Entries cannot overlap; they can be nested. So there is only one - entry at most that corresponds to the current instruction, and that - is the entry on the top of the stack. */ - struct eh_stack x_ehstack; - /* This stack is used to represent what the current eh region is - for the catch blocks beings processed */ - struct eh_stack x_catchstack; - /* A queue used for tracking which exception regions have closed. - As we exit a region, we enqueue a new entry. The entries are then - dequeued during expand_leftover_cleanups and - expand_start_all_catch. */ - struct eh_queue *x_ehqueue; - /* Insns for all of the exception handlers for the current function. - They are currently emitted by the frontend code. */ - rtx x_catch_clauses; - /* End of exception handler insn sequence. */ - rtx x_catch_clauses_last; - /* A random data area for the front end's own use. */ - struct label_node *x_false_label_stack; - /* Keeps track of the label to resume to should one want to resume - normal control flow out of a handler (instead of, say, returning to - the caller of the current function or exiting the program). */ - struct label_node *x_caught_return_label_stack; - /* A stack (TREE_LIST) of lists of handlers. The TREE_VALUE of each - node is itself a TREE_CHAINed list of handlers for regions that - are not yet closed. The TREE_VALUE of each entry contains the - handler for the corresponding entry on the ehstack. */ - union tree_node *x_protect_list; - /* The EH context. Nonzero if the function has already - fetched a pointer to the EH context for exception handling. */ - rtx ehc; - /* The label generated by expand_builtin_eh_return. */ - rtx x_eh_return_stub_label; -}; - -#define ehstack (cfun->eh->x_ehstack) -#define catchstack (cfun->eh->x_catchstack) -#define ehqueue (cfun->eh->x_ehqueue) -#define catch_clauses (cfun->eh->x_catch_clauses) -#define catch_clauses_last (cfun->eh->x_catch_clauses_last) -#define false_label_stack (cfun->eh->x_false_label_stack) -#define caught_return_label_stack (cfun->eh->x_caught_return_label_stack) -#define protect_list (cfun->eh->x_protect_list) -#define current_function_ehc (cfun->eh->ehc) -#define eh_return_stub_label (cfun->eh->x_eh_return_stub_label) - -#ifdef TREE_CODE -/* Start an exception handling region. All instructions emitted after - this point are considered to be part of the region until - expand_eh_region_end () is invoked. */ - -extern void expand_eh_region_start PARAMS ((void)); - -/* Just like expand_eh_region_start, except if a cleanup action is - entered on the cleanup chain, the TREE_PURPOSE of the element put - on the chain is DECL. DECL should be the associated VAR_DECL, if - any, otherwise it should be NULL_TREE. */ - -extern void expand_eh_region_start_for_decl PARAMS ((tree)); - -/* Start an exception handling region for the given cleanup action. - All instructions emitted after this point are considered to be part - of the region until expand_eh_region_end () is invoked. CLEANUP is - the cleanup action to perform. The return value is true if the - exception region was optimized away. If that case, - expand_eh_region_end does not need to be called for this cleanup, - nor should it be. - - This routine notices one particular common case in C++ code - generation, and optimizes it so as to not need the exception - region. */ - -extern int expand_eh_region_start_tree PARAMS ((tree, tree)); - -/* End an exception handling region. The information about the region - is found on the top of ehstack. - - HANDLER is either the cleanup for the exception region, or if we're - marking the end of a try block, HANDLER is integer_zero_node. - - HANDLER will be transformed to rtl when expand_leftover_cleanups () - is invoked. */ - -extern void expand_eh_region_end PARAMS ((tree)); - -/* Push RLABEL or TLABEL onto LABELSTACK. Only one of RLABEL or TLABEL - should be set; the other must be NULL. */ - -extern void push_label_entry PARAMS ((struct label_node **labelstack, - rtx rlabel, tree tlabel)); - -/* Pop the topmost entry from LABELSTACK and return its value as an - rtx node. If LABELSTACK is empty, return NULL. */ - -extern rtx pop_label_entry PARAMS ((struct label_node **labelstack)); - -/* Return the topmost entry of LABELSTACK as a tree node, or return - NULL_TREE if LABELSTACK is empty. */ - -extern tree top_label_entry PARAMS ((struct label_node **labelstack)); - +#ifndef RTX_CODE +struct rtx_def; +#define rtx struct rtx_def * #endif -/* Test: is exception handling turned on? */ - -extern int doing_eh PARAMS ((int)); - -/* Toplevel initialization for EH. */ - -void set_exception_lang_code PARAMS ((int)); -void set_exception_version_code PARAMS ((int)); - -/* A list of handlers asocciated with an exception region. HANDLER_LABEL - is the the label that control should be transfered to if the data - in TYPE_INFO matches an exception. a value of NULL_TREE for TYPE_INFO - means This is a cleanup, and must always be called. A value of - CATCH_ALL_TYPE works like a cleanup, but a call to the runtime matcher - is still performed to avoid being caught by a different language - exception. NEXT is a pointer to the next handler for this region. - NULL means there are no more. */ - -typedef struct handler_info -{ - rtx handler_label; - int handler_number; - void *type_info; - struct handler_info *next; -} handler_info; - - -/* Add new handler information to an exception range. The first parameter - specifies the range number (returned from new_eh_entry()). The second - parameter specifies the handler. By default the handler is inserted at - the end of the list. A handler list may contain only ONE NULL_TREE - typeinfo entry. Regardless where it is positioned, a NULL_TREE entry - is always output as the LAST handler in the exception table for a region. */ - -void add_new_handler PARAMS ((int, struct handler_info *)); - -/* Remove a handler label. The handler label is being deleted, so all - regions which reference this handler should have it removed from their - list of possible handlers. Any region which has the final handler - removed can be deleted. */ - -void remove_handler PARAMS ((rtx)); - -/* Create a new handler structure initialized with the handler label and - typeinfo fields passed in. */ - -struct handler_info *get_new_handler PARAMS ((rtx, void *)); - -/* Make a duplicate of an exception region by copying all the handlers - for an exception region. Return the new handler index. */ - -int duplicate_eh_handlers PARAMS ((int, int, rtx (*)(rtx))); - -/* map symbol refs for rethrow */ - -rtx rethrow_symbol_map PARAMS ((rtx, rtx (*)(rtx))); - -/* Is the rethrow label for a region used? */ - -int rethrow_used PARAMS ((int)); - -/* Update the rethrow references to reflect rethrows which have been - optimized away. */ - -void update_rethrow_references PARAMS ((void)); - -/* Get a pointer to the first handler in an exception region's list. */ - -struct handler_info *get_first_handler PARAMS ((int)); - -/* Find all the runtime handlers type matches currently referenced */ - -int find_all_handler_type_matches PARAMS ((void ***)); - -/* The eh_nesting_info structure is used to find a list of valid handlers - for any arbitrary exception region. When init_eh_nesting_info is called, - the information is all pre-calculated and entered in this structure. - REGION_INDEX is a vector over all possible region numbers. Since the - number of regions is typically much smaller than the range of block - numbers, this is a sparse vector and the other data structures are - represented as dense vectors. Indexed with an exception region number, this - returns the index to use in the other data structures to retreive the - correct information. - HANDLERS is an array of vectors which point to handler_info structures. - when indexed, it gives the list of all possible handlers which can - be reached by a throw from this exception region. - NUM_HANDLERS is the equivilent array indicating how many handler - pointers there are in the HANDLERS vector. - OUTER_INDEX indicates which index represents the information for the - outer block. 0 indicates there is no outer context. - REGION_COUNT is the number of regions. */ - -typedef struct eh_nesting -{ - int *region_index; - handler_info ***handlers; - int *num_handlers; - int *outer_index; - int region_count; -} eh_nesting_info; - -/* Initialize the eh_nesting_info structure. */ - -eh_nesting_info *init_eh_nesting_info PARAMS ((void)); - -/* Get a list of handlers reachable from a an exception region/insn. */ - -int reachable_handlers PARAMS ((int, eh_nesting_info *, rtx, - handler_info ***handlers)); - -/* Free the eh_nesting_info structure. */ - -void free_eh_nesting_info PARAMS ((eh_nesting_info *)); - -extern void init_eh PARAMS ((void)); - -/* Initialization for the per-function EH data. */ - -extern void init_eh_for_function PARAMS ((void)); - -/* Generate an exception label. Use instead of gen_label_rtx */ - -extern rtx gen_exception_label PARAMS ((void)); - -/* Adds an EH table entry for EH entry number N. Called from - final_scan_insn for NOTE_INSN_EH_REGION_BEG. */ - -extern void add_eh_table_entry PARAMS ((int n)); - -/* Start a catch clause, triggered by runtime value paramter. */ - -#ifdef TREE_CODE -extern void start_catch_handler PARAMS ((tree)); +#ifndef _VARRAY_H_ +struct varray_head_tag; +#define varray_type struct varray_head_tag * #endif -/* End an individual catch clause. */ - -extern void end_catch_handler PARAMS ((void)); - -/* Returns a non-zero value if we need to output an exception table. */ - -extern int exception_table_p PARAMS ((void)); - -/* Outputs the exception table if we have one. */ -extern void output_exception_table PARAMS ((void)); -extern void output_exception_table_data PARAMS ((void)); +/* Per-function EH data. Used only in except.c, but GC and others + manipulate pointers to the opaque type. */ +struct eh_status; -/* Free the exception table. */ +/* Internal structure describing a region. */ +struct eh_region; -extern void free_exception_table PARAMS((void)); +/* Test: is exception handling turned on? */ +extern int doing_eh PARAMS ((int)); -/* Used by the ia64 unwind format to output data for an individual - function. */ +/* Start an exception handling region. All instructions emitted after + this point are considered to be part of the region until an + expand_eh_region_end variant is invoked. */ +extern void expand_eh_region_start PARAMS ((void)); -extern void output_function_exception_table PARAMS((void)); +/* End an exception handling region for a cleanup. HANDLER is an + expression to expand for the cleanup. */ +extern void expand_eh_region_end_cleanup PARAMS ((tree)); -/* Given a return address in ADDR, determine the address we should use - to find the corresponding EH region. */ +/* End an exception handling region for a try block, and prepares + for subsequent calls to expand_start_catch. */ +extern void expand_start_all_catch PARAMS ((void)); -extern rtx eh_outer_context PARAMS ((rtx addr)); +/* Begin a catch clause. TYPE is an object to be matched by the + runtime, or null if this is a catch-all clause. */ +extern void expand_start_catch PARAMS ((tree)); -/* Called at the start of a block of try statements for which there is - a supplied catch handler. */ +/* End a catch clause. Control will resume after the try/catch block. */ +extern void expand_end_catch PARAMS ((void)); -extern void expand_start_try_stmts PARAMS ((void)); +/* End a sequence of catch handlers for a try block. */ +extern void expand_end_all_catch PARAMS ((void)); -/* Called at the start of a block of catch statements. It terminates the - previous set of try statements. */ +/* End an exception region for an exception type filter. ALLOWED is a + TREE_LIST of TREE_VALUE objects to be matched by the runtime. + FAILURE is a function to invoke if a mismatch ocurrs. */ +extern void expand_eh_region_end_allowed PARAMS ((tree, tree)); -extern void expand_start_all_catch PARAMS ((void)); +/* End an exception region for a must-not-throw filter. FAILURE is a + function to invoke if an uncaught exception propagates this far. */ +extern void expand_eh_region_end_must_not_throw PARAMS ((tree)); -/* Called at the end of a block of catch statements. */ +/* End an exception region for a throw. No handling goes on here, + but it's the easiest way for the front-end to indicate what type + is being thrown. */ +extern void expand_eh_region_end_throw PARAMS ((tree)); -extern void expand_end_all_catch PARAMS ((void)); +/* End a fixup region. Within this region the cleanups for the immediately + enclosing region are _not_ run. This is used for goto cleanup to avoid + destroying an object twice. */ +extern void expand_eh_region_end_fixup PARAMS ((tree)); /* Begin a region that will contain entries created with add_partial_entry. */ - extern void begin_protect_partials PARAMS ((void)); -#ifdef TREE_CODE /* Create a new exception region and add the handler for the region - onto a list. These regions will be ended (and their handlers - emitted) when end_protect_partials is invoked. */ - -extern void add_partial_entry PARAMS ((tree handler)); -#endif + onto a list. These regions will be ended (and their handlers emitted) + when end_protect_partials is invoked. */ +extern void add_partial_entry PARAMS ((tree)); /* End all of the pending exception regions that have handlers added with - push_protect_entry (). */ - + add_partial_entry. */ extern void end_protect_partials PARAMS ((void)); -/* An internal throw. */ - -extern void expand_internal_throw PARAMS ((void)); - -/* Called from expand_exception_blocks and expand_end_catch_block to - expand and pending handlers. */ - -extern void expand_leftover_cleanups PARAMS ((void)); - -/* If necessary, emit insns to get EH context for the current - function. */ - -extern void emit_eh_context PARAMS ((void)); - -/* Builds a list of handler labels and puts them in the global - variable exception_handler_labels. */ - -extern void find_exception_handler_labels PARAMS ((void)); - -/* Determine if an arbitrary label is an exception label */ - -extern int is_exception_handler_label PARAMS ((int)); - -/* Performs sanity checking on the check_exception_handler_labels - list. */ - -extern void check_exception_handler_labels PARAMS ((void)); - -/* Keeps track of the label used as the context of a throw to rethrow an - exception to the outer exception region. */ - -extern struct label_node *outer_context_label_stack; - -/* A list of labels used for exception handlers. It is created by - find_exception_handler_labels for the optimization passes. */ +/* A list of labels used for exception handlers. */ extern rtx exception_handler_labels; /* Determine if the given INSN can throw an exception. */ - -extern int can_throw_internal PARAMS ((rtx)); +extern bool can_throw_internal PARAMS ((rtx)); +extern bool can_throw_external PARAMS ((rtx)); /* Return nonzero if nothing in this function can throw. */ +extern bool nothrow_function_p PARAMS ((void)); -extern int nothrow_function_p PARAMS ((void)); +/* After initial rtl generation, call back to finish generating + exception support code. */ +extern void finish_eh_generation PARAMS ((void)); -/* Performs optimizations for exception handling, such as removing - unnecessary exception regions. Invoked from jump_optimize (). */ +extern void init_eh PARAMS ((void)); +extern void init_eh_for_function PARAMS ((void)); -extern void exception_optimize PARAMS ((void)); +extern rtx reachable_handlers PARAMS ((rtx)); +extern void maybe_remove_eh_handler PARAMS ((rtx)); -/* Return EH context (and set it up once per fn). */ -extern rtx get_eh_context PARAMS ((void)); +extern void convert_from_eh_region_ranges PARAMS ((void)); +extern void convert_to_eh_region_ranges PARAMS ((void)); +extern void find_exception_handler_labels PARAMS ((void)); +extern void output_function_exception_table PARAMS ((void)); -/* Get the dynamic handler chain. */ -extern rtx get_dynamic_handler_chain PARAMS ((void)); +extern void expand_builtin_unwind_init PARAMS ((void)); +extern rtx expand_builtin_eh_return_data_regno PARAMS ((tree)); +extern rtx expand_builtin_extract_return_addr PARAMS ((tree)); +extern rtx expand_builtin_frob_return_addr PARAMS ((tree)); +extern void expand_builtin_eh_return PARAMS ((tree, tree)); +extern void expand_eh_return PARAMS ((void)); -/* Get the dynamic cleanup chain. */ -extern rtx get_dynamic_cleanup_chain PARAMS ((void)); +extern rtx get_exception_pointer PARAMS ((void)); -/* Throw an exception. */ +struct function; +struct inline_remap; +extern int duplicate_eh_regions PARAMS ((struct function *, + struct inline_remap *)); -extern void emit_throw PARAMS ((void)); +extern void sjlj_emit_function_exit_after PARAMS ((rtx)); -/* Save away the current ehqueue. */ -extern void push_ehqueue PARAMS ((void)); -/* Restore a previously pushed ehqueue. */ -extern void pop_ehqueue PARAMS ((void)); +/* Nonzero to protect cleanup actions with must-not-throw regions. */ +extern tree protect_cleanup_actions; -/* One to protect cleanup actions with a handler that calls - __terminate, zero otherwise. */ +/* Return true if type A catches type B. */ +int (*lang_eh_type_covers) PARAMS ((tree a, tree b)); -extern int protect_cleanup_actions_with_terminate; +/* Map a type to a runtime object to match type. */ +tree (*lang_eh_runtime_type) PARAMS ((tree)); -#ifdef TREE_CODE -extern tree protect_with_terminate PARAMS ((tree)); +#ifndef TREE_CODE +#undef tree #endif -extern void expand_fixup_region_start PARAMS ((void)); -#ifdef TREE_CODE -extern void expand_fixup_region_end PARAMS ((tree)); +#ifndef RTX_CODE +#undef rtx #endif -/* Various hooks for the DWARF 2 __throw routine. */ - -void expand_builtin_unwind_init PARAMS ((void)); -rtx expand_builtin_dwarf_fp_regnum PARAMS ((void)); -#ifdef TREE_CODE -rtx expand_builtin_frob_return_addr PARAMS ((tree)); -rtx expand_builtin_extract_return_addr PARAMS ((tree)); -void expand_builtin_init_dwarf_reg_sizes PARAMS ((tree)); -void expand_builtin_eh_return PARAMS ((tree, tree, tree)); +#ifndef _VARRAY_H_ +#undef varray_type #endif -void expand_eh_return PARAMS ((void)); - - -/* Checking whether 2 instructions are within the same exception region. */ -int in_same_eh_region PARAMS ((rtx, rtx)); -void free_insn_eh_region PARAMS ((void)); -void init_insn_eh_region PARAMS ((rtx, int)); - -#ifdef rtx -#undef rtx -#endif /* Just because the user configured --with-sjlj-exceptions=no doesn't mean that we can use call frame exceptions. Detect that the target has appropriate support. */ +#if !defined (EH_RETURN_DATA_REGNO) \ + || !defined(EH_RETURN_STACKADJ_RTX) \ + || ! (defined(EH_RETURN_HANDLER_RTX) \ + || defined(HAVE_eh_return)) \ + || ! (defined(DWARF2_UNWIND_INFO) \ + || defined(IA64_UNWIND_INFO)) +#define MUST_USE_SJLJ_EXCEPTIONS 1 +#else +#define MUST_USE_SJLJ_EXCEPTIONS 0 +#endif + #ifdef CONFIG_SJLJ_EXCEPTIONS # if CONFIG_SJLJ_EXCEPTIONS == 1 # define USING_SJLJ_EXCEPTIONS 1 # endif # if CONFIG_SJLJ_EXCEPTIONS == 0 # define USING_SJLJ_EXCEPTIONS 0 +# ifndef EH_RETURN_DATA_REGNO + #error "EH_RETURN_DATA_REGNO required" +# endif +# ifndef EH_RETURN_STACKADJ_RTX + #error "EH_RETURN_STACKADJ_RTX required" +# endif +# if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return) + #error "EH_RETURN_HANDLER_RTX or eh_return required" +# endif # if !defined(DWARF2_UNWIND_INFO) && !defined(IA64_UNWIND_INFO) #error "{DWARF2,IA64}_UNWIND_INFO required" # endif # endif #else -# ifdef IA64_UNWIND_INFO -# define USING_SJLJ_EXCEPTIONS (!IA64_UNWIND_INFO) -# else -# ifdef DWARF2_UNWIND_INFO -# define USING_SJLJ_EXCEPTIONS (!DWARF2_UNWIND_INFO) -# endif -# endif +# define USING_SJLJ_EXCEPTIONS MUST_USE_SJLJ_EXCEPTIONS #endif diff --git a/gcc/expr.c b/gcc/expr.c index ac683dbf1b6..c2661722cb3 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8741,7 +8741,7 @@ expand_expr (exp, target, tmode, modifier) op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0); - expand_eh_region_end (handler); + expand_eh_region_end_cleanup (handler); return op0; } @@ -8788,23 +8788,12 @@ expand_expr (exp, target, tmode, modifier) return const0_rtx; } - case POPDCC_EXPR: - { - rtx dcc = get_dynamic_cleanup_chain (); - emit_move_insn (dcc, validize_mem (gen_rtx_MEM (Pmode, dcc))); - return const0_rtx; - } - - case POPDHC_EXPR: - { - rtx dhc = get_dynamic_handler_chain (); - emit_move_insn (dhc, validize_mem (gen_rtx_MEM (Pmode, dhc))); - return const0_rtx; - } - case VA_ARG_EXPR: return expand_builtin_va_arg (TREE_OPERAND (exp, 0), type); + case EXC_PTR_EXPR: + return get_exception_pointer (); + default: return (*lang_expand_expr) (exp, original_target, tmode, modifier); } diff --git a/gcc/expr.h b/gcc/expr.h index b1f2765e5c0..8d883017eb1 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -495,14 +495,12 @@ enum libfunc_index LTI_memset, LTI_bzero, - LTI_throw, - LTI_rethrow, - LTI_sjthrow, - LTI_sjpopnthrow, - LTI_terminate, + LTI_unwind_resume, + LTI_eh_personality, LTI_setjmp, LTI_longjmp, - LTI_eh_rtime_match, + LTI_unwind_sjlj_register, + LTI_unwind_sjlj_unregister, LTI_eqhf2, LTI_nehf2, @@ -628,14 +626,13 @@ extern rtx libfunc_table[LTI_MAX]; #define memset_libfunc (libfunc_table[LTI_memset]) #define bzero_libfunc (libfunc_table[LTI_bzero]) -#define throw_libfunc (libfunc_table[LTI_throw]) -#define rethrow_libfunc (libfunc_table[LTI_rethrow]) -#define sjthrow_libfunc (libfunc_table[LTI_sjthrow]) -#define sjpopnthrow_libfunc (libfunc_table[LTI_sjpopnthrow]) -#define terminate_libfunc (libfunc_table[LTI_terminate]) +#define unwind_resume_libfunc (libfunc_table[LTI_unwind_resume]) +#define eh_personality_libfunc (libfunc_table[LTI_eh_personality]) #define setjmp_libfunc (libfunc_table[LTI_setjmp]) #define longjmp_libfunc (libfunc_table[LTI_longjmp]) -#define eh_rtime_match_libfunc (libfunc_table[LTI_eh_rtime_match]) +#define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register]) +#define unwind_sjlj_unregister_libfunc \ + (libfunc_table[LTI_unwind_sjlj_unregister]) #define eqhf2_libfunc (libfunc_table[LTI_eqhf2]) #define nehf2_libfunc (libfunc_table[LTI_nehf2]) diff --git a/gcc/final.c b/gcc/final.c index 7b65a02ce71..fef6641a3a6 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1945,8 +1945,6 @@ final (first, file, optimize, prescan) last_ignored_compare = 0; new_block = 1; - check_exception_handler_labels (); - /* Make a map indicating which line numbers appear in this function. When producing SDB debugging info, delete troublesome line number notes from inlined functions in other files as well as duplicate @@ -2003,10 +2001,6 @@ final (first, file, optimize, prescan) #endif } - /* Initialize insn_eh_region table if eh is being used. */ - - init_insn_eh_region (first, max_uid); - init_recog (); CC_STATUS_INIT; @@ -2040,7 +2034,6 @@ final (first, file, optimize, prescan) if (profile_block_flag && new_block) add_bb (file); - free_insn_eh_region (); free (line_note_exists); line_note_exists = NULL; } @@ -2126,24 +2119,13 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) break; case NOTE_INSN_EH_REGION_BEG: - if (! USING_SJLJ_EXCEPTIONS) - { - ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_EH_HANDLER (insn)); -#ifdef ASM_OUTPUT_EH_REGION_BEG - ASM_OUTPUT_EH_REGION_BEG (file, NOTE_EH_HANDLER (insn)); -#endif - } + ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB", + NOTE_EH_HANDLER (insn)); break; case NOTE_INSN_EH_REGION_END: - if (! USING_SJLJ_EXCEPTIONS) - { - ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_EH_HANDLER (insn)); - add_eh_table_entry (NOTE_EH_HANDLER (insn)); -#ifdef ASM_OUTPUT_EH_REGION_END - ASM_OUTPUT_EH_REGION_END (file, NOTE_EH_HANDLER (insn)); -#endif - } + ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE", + NOTE_EH_HANDLER (insn)); break; case NOTE_INSN_PROLOGUE_END: diff --git a/gcc/flow.c b/gcc/flow.c index 75dc09c4b74..d057bc5e264 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -204,7 +204,6 @@ struct basic_block_def entry_exit_blocks[2] NULL, /* aux */ ENTRY_BLOCK, /* index */ 0, /* loop_depth */ - -1, -1, /* eh_beg, eh_end */ 0 /* count */ }, { @@ -219,7 +218,6 @@ struct basic_block_def entry_exit_blocks[2] NULL, /* aux */ EXIT_BLOCK, /* index */ 0, /* loop_depth */ - -1, -1, /* eh_beg, eh_end */ 0 /* count */ } }; @@ -368,16 +366,12 @@ static void clear_edges PARAMS ((void)); static void make_edges PARAMS ((rtx)); static void make_label_edge PARAMS ((sbitmap *, basic_block, rtx, int)); -static void make_eh_edge PARAMS ((sbitmap *, eh_nesting_info *, - basic_block, rtx, int)); +static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx)); static void mark_critical_edges PARAMS ((void)); -static void move_stray_eh_region_notes PARAMS ((void)); -static void record_active_eh_regions PARAMS ((rtx)); static void commit_one_edge_insertion PARAMS ((edge)); static void delete_unreachable_blocks PARAMS ((void)); -static void delete_eh_regions PARAMS ((void)); static int can_delete_note_p PARAMS ((rtx)); static void expunge_block PARAMS ((basic_block)); static int can_delete_label_p PARAMS ((rtx)); @@ -537,7 +531,6 @@ find_basic_blocks (f, nregs, file) compute_bb_for_insn (max_uid); /* Discover the edges of our cfg. */ - record_active_eh_regions (f); make_edges (label_value_list); /* Do very simple cleanup now, for the benefit of code that runs between @@ -599,46 +592,45 @@ count_basic_blocks (f) register rtx insn; register RTX_CODE prev_code; register int count = 0; - int eh_region = 0; - int call_had_abnormal_edge = 0; + int saw_abnormal_edge = 0; prev_code = JUMP_INSN; for (insn = f; insn; insn = NEXT_INSN (insn)) { - register RTX_CODE code = GET_CODE (insn); + enum rtx_code code = GET_CODE (insn); if (code == CODE_LABEL || (GET_RTX_CLASS (code) == 'i' && (prev_code == JUMP_INSN || prev_code == BARRIER - || (prev_code == CALL_INSN && call_had_abnormal_edge)))) - count++; + || saw_abnormal_edge))) + { + saw_abnormal_edge = 0; + count++; + } - /* Record whether this call created an edge. */ + /* Record whether this insn created an edge. */ if (code == CALL_INSN) { - rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - int region = (note ? INTVAL (XEXP (note, 0)) : 1); - - call_had_abnormal_edge = 0; - - /* If there is an EH region or rethrow, we have an edge. */ - if ((eh_region && region > 0) - || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX)) - call_had_abnormal_edge = 1; - else if (nonlocal_goto_handler_labels && region >= 0) - /* If there is a nonlocal goto label and the specified - region number isn't -1, we have an edge. (0 means - no throw, but might have a nonlocal goto). */ - call_had_abnormal_edge = 1; + rtx note; + + /* If there is a nonlocal goto label and the specified + region number isn't -1, we have an edge. */ + if (nonlocal_goto_handler_labels + && ((note = find_reg_note (insn, REG_EH_REGION, NULL_RTX)) == 0 + || INTVAL (XEXP (note, 0)) >= 0)) + saw_abnormal_edge = 1; + + else if (can_throw_internal (insn)) + saw_abnormal_edge = 1; } + else if (flag_non_call_exceptions + && code == INSN + && can_throw_internal (insn)) + saw_abnormal_edge = 1; if (code != NOTE) prev_code = code; - else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - ++eh_region; - else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END) - --eh_region; } /* The rest of the compiler works a bit smoother when we don't have to @@ -672,9 +664,6 @@ find_label_refs (f, lvl) Make a special exception for labels followed by an ADDR*VEC, as this would be a part of the tablejump setup code. - Make a special exception for the eh_return_stub_label, which - we know isn't part of any otherwise visible control flow. - Make a special exception to registers loaded with label values just before jump insns that use them. */ @@ -683,9 +672,7 @@ find_label_refs (f, lvl) { rtx lab = XEXP (note, 0), next; - if (lab == eh_return_stub_label) - ; - else if ((next = next_nonnote_insn (lab)) != NULL + if ((next = next_nonnote_insn (lab)) != NULL && GET_CODE (next) == JUMP_INSN && (GET_CODE (PATTERN (next)) == ADDR_VEC || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC)) @@ -815,7 +802,6 @@ find_basic_blocks_1 (f) register rtx insn, next; int i = 0; rtx bb_note = NULL_RTX; - rtx eh_list = NULL_RTX; rtx lvl = NULL_RTX; rtx trll = NULL_RTX; rtx head = NULL_RTX; @@ -839,22 +825,11 @@ find_basic_blocks_1 (f) { int kind = NOTE_LINE_NUMBER (insn); - /* Keep a LIFO list of the currently active exception notes. */ - if (kind == NOTE_INSN_EH_REGION_BEG) - eh_list = alloc_INSN_LIST (insn, eh_list); - else if (kind == NOTE_INSN_EH_REGION_END) - { - rtx t = eh_list; - - eh_list = XEXP (eh_list, 1); - free_INSN_LIST_node (t); - } - /* Look for basic block notes with which to keep the basic_block_info pointers stable. Unthread the note now; we'll put it back at the right place in create_basic_block. Or not at all if we've already found a note in this block. */ - else if (kind == NOTE_INSN_BASIC_BLOCK) + if (kind == NOTE_INSN_BASIC_BLOCK) { if (bb_note == NULL_RTX) bb_note = insn; @@ -938,8 +913,7 @@ find_basic_blocks_1 (f) { /* Record whether this call created an edge. */ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); - int region = (note ? INTVAL (XEXP (note, 0)) : 1); - int call_has_abnormal_edge = 0; + int region = (note ? INTVAL (XEXP (note, 0)) : 0); if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER) { @@ -952,19 +926,10 @@ find_basic_blocks_1 (f) trll = alloc_EXPR_LIST (0, XEXP (PATTERN (insn), 3), trll); } - /* If there is an EH region or rethrow, we have an edge. */ - if ((eh_list && region > 0) - || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX)) - call_has_abnormal_edge = 1; - else if (nonlocal_goto_handler_labels && region >= 0) - /* If there is a nonlocal goto label and the specified - region number isn't -1, we have an edge. (0 means - no throw, but might have a nonlocal goto). */ - call_has_abnormal_edge = 1; - /* A basic block ends at a call that can either throw or do a non-local goto. */ - if (call_has_abnormal_edge) + if ((nonlocal_goto_handler_labels && region >= 0) + || can_throw_internal (insn)) { new_bb_inclusive: if (head == NULL_RTX) @@ -980,18 +945,21 @@ find_basic_blocks_1 (f) } /* Fall through. */ - default: - if (GET_RTX_CLASS (code) == 'i') - { - if (head == NULL_RTX) - head = insn; - end = insn; - } + case INSN: + /* Non-call exceptions generate new blocks just like calls. */ + if (flag_non_call_exceptions && can_throw_internal (insn)) + goto new_bb_inclusive; + + if (head == NULL_RTX) + head = insn; + end = insn; break; + + default: + abort (); } - if (GET_RTX_CLASS (code) == 'i' - && GET_CODE (insn) != JUMP_INSN) + if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN) { rtx note; @@ -1000,9 +968,6 @@ find_basic_blocks_1 (f) Make a special exception for labels followed by an ADDR*VEC, as this would be a part of the tablejump setup code. - Make a special exception for the eh_return_stub_label, which - we know isn't part of any otherwise visible control flow. - Make a special exception to registers loaded with label values just before jump insns that use them. */ @@ -1011,9 +976,7 @@ find_basic_blocks_1 (f) { rtx lab = XEXP (note, 0), next; - if (lab == eh_return_stub_label) - ; - else if ((next = next_nonnote_insn (lab)) != NULL + if ((next = next_nonnote_insn (lab)) != NULL && GET_CODE (next) == JUMP_INSN && (GET_CODE (PATTERN (next)) == ADDR_VEC || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC)) @@ -1047,8 +1010,6 @@ void cleanup_cfg () { delete_unreachable_blocks (); - move_stray_eh_region_notes (); - record_active_eh_regions (get_insns ()); try_merge_blocks (); mark_critical_edges (); @@ -1201,7 +1162,6 @@ make_edges (label_value_list) rtx label_value_list; { int i; - eh_nesting_info *eh_nest_info = init_eh_nesting_info (); sbitmap *edge_cache = NULL; /* Assume no computed jump; revise as we create edges. */ @@ -1241,9 +1201,13 @@ make_edges (label_value_list) { rtx tmp; + /* Recognize exception handling placeholders. */ + if (GET_CODE (PATTERN (insn)) == RESX) + make_eh_edge (edge_cache, bb, insn); + /* Recognize a non-local goto as a branch outside the current function. */ - if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) + else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) ; /* ??? Recognize a tablejump and do the right thing. */ @@ -1318,37 +1282,15 @@ make_edges (label_value_list) EDGE_ABNORMAL | EDGE_ABNORMAL_CALL); /* If this is a CALL_INSN, then mark it as reaching the active EH - handler for this CALL_INSN. If we're handling asynchronous + handler for this CALL_INSN. If we're handling non-call exceptions then any insn can reach any of the active handlers. Also mark the CALL_INSN as reaching any nonlocal goto handler. */ else if (code == CALL_INSN || flag_non_call_exceptions) { - /* Add any appropriate EH edges. We do this unconditionally - since there may be a REG_EH_REGION or REG_EH_RETHROW note - on the call, and this needn't be within an EH region. */ - make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end); - - /* If we have asynchronous exceptions, do the same for *all* - exception regions active in the block. */ - if (flag_non_call_exceptions - && bb->eh_beg != bb->eh_end) - { - if (bb->eh_beg >= 0) - make_eh_edge (edge_cache, eh_nest_info, bb, - NULL_RTX, bb->eh_beg); - - for (x = bb->head; x != bb->end; x = NEXT_INSN (x)) - if (GET_CODE (x) == NOTE - && (NOTE_LINE_NUMBER (x) == NOTE_INSN_EH_REGION_BEG - || NOTE_LINE_NUMBER (x) == NOTE_INSN_EH_REGION_END)) - { - int region = NOTE_EH_HANDLER (x); - make_eh_edge (edge_cache, eh_nest_info, bb, - NULL_RTX, region); - } - } + /* Add any appropriate EH edges. */ + make_eh_edge (edge_cache, bb, insn); if (code == CALL_INSN && nonlocal_goto_handler_labels) { @@ -1369,14 +1311,6 @@ make_edges (label_value_list) } } - /* We know something about the structure of the function __throw in - libgcc2.c. It is the only function that ever contains eh_stub - labels. It modifies its return address so that the last block - returns to one of the eh_stub labels within it. So we have to - make additional edges in the flow graph. */ - if (i + 1 == n_basic_blocks && eh_return_stub_label != 0) - make_label_edge (edge_cache, bb, eh_return_stub_label, EDGE_EH); - /* Find out if we can drop through to the next block. */ insn = next_nonnote_insn (insn); if (!insn || (i + 1 == n_basic_blocks && force_fallthru)) @@ -1391,7 +1325,6 @@ make_edges (label_value_list) } } - free_eh_nesting_info (eh_nest_info); if (edge_cache) sbitmap_vector_free (edge_cache); } @@ -1479,115 +1412,21 @@ make_label_edge (edge_cache, src, label, flags) /* Create the edges generated by INSN in REGION. */ static void -make_eh_edge (edge_cache, eh_nest_info, src, insn, region) +make_eh_edge (edge_cache, src, insn) sbitmap *edge_cache; - eh_nesting_info *eh_nest_info; basic_block src; rtx insn; - int region; -{ - handler_info **handler_list; - int num, is_call; - - is_call = (insn && GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0); - num = reachable_handlers (region, eh_nest_info, insn, &handler_list); - while (--num >= 0) - { - make_label_edge (edge_cache, src, handler_list[num]->handler_label, - EDGE_ABNORMAL | EDGE_EH | is_call); - } -} - -/* EH_REGION notes appearing between basic blocks is ambiguous, and even - dangerous if we intend to move basic blocks around. Move such notes - into the following block. */ - -static void -move_stray_eh_region_notes () -{ - int i; - basic_block b1, b2; - - if (n_basic_blocks < 2) - return; - - b2 = BASIC_BLOCK (n_basic_blocks - 1); - for (i = n_basic_blocks - 2; i >= 0; --i, b2 = b1) - { - rtx insn, next, list = NULL_RTX; - - b1 = BASIC_BLOCK (i); - for (insn = NEXT_INSN (b1->end); insn != b2->head; insn = next) - { - next = NEXT_INSN (insn); - if (GET_CODE (insn) == NOTE - && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) - { - /* Unlink from the insn chain. */ - NEXT_INSN (PREV_INSN (insn)) = next; - PREV_INSN (next) = PREV_INSN (insn); - - /* Queue it. */ - NEXT_INSN (insn) = list; - list = insn; - } - } - - if (list == NULL_RTX) - continue; - - /* Find where to insert these things. */ - insn = b2->head; - if (GET_CODE (insn) == CODE_LABEL) - insn = NEXT_INSN (insn); - - while (list) - { - next = NEXT_INSN (list); - add_insn_after (list, insn); - list = next; - } - } -} - -/* Recompute eh_beg/eh_end for each basic block. */ - -static void -record_active_eh_regions (f) - rtx f; { - rtx insn, eh_list = NULL_RTX; - int i = 0; - basic_block bb = BASIC_BLOCK (0); + int is_call = (GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0); + rtx handlers, i; - for (insn = f; insn; insn = NEXT_INSN (insn)) - { - if (bb->head == insn) - bb->eh_beg = (eh_list ? NOTE_EH_HANDLER (XEXP (eh_list, 0)) : -1); + handlers = reachable_handlers (insn); - if (GET_CODE (insn) == NOTE) - { - int kind = NOTE_LINE_NUMBER (insn); - if (kind == NOTE_INSN_EH_REGION_BEG) - eh_list = alloc_INSN_LIST (insn, eh_list); - else if (kind == NOTE_INSN_EH_REGION_END) - { - rtx t = XEXP (eh_list, 1); - free_INSN_LIST_node (eh_list); - eh_list = t; - } - } + for (i = handlers; i; i = XEXP (i, 1)) + make_label_edge (edge_cache, src, XEXP (i, 0), + EDGE_ABNORMAL | EDGE_EH | is_call); - if (bb->end == insn) - { - bb->eh_end = (eh_list ? NOTE_EH_HANDLER (XEXP (eh_list, 0)) : -1); - i += 1; - if (i == n_basic_blocks) - break; - bb = BASIC_BLOCK (i); - } - } + free_INSN_LIST_list (&handlers); } /* Identify critical edges and set the bits appropriately. */ @@ -2223,7 +2062,6 @@ static void delete_unreachable_blocks () { basic_block *worklist, *tos; - int deleted_handler; edge e; int i, n; @@ -2261,10 +2099,9 @@ delete_unreachable_blocks () } } - /* Delete all unreachable basic blocks. Count down so that we don't - interfere with the block renumbering that happens in flow_delete_block. */ - - deleted_handler = 0; + /* Delete all unreachable basic blocks. Count down so that we + don't interfere with the block renumbering that happens in + flow_delete_block. */ for (i = n - 1; i >= 0; --i) { @@ -2274,46 +2111,14 @@ delete_unreachable_blocks () /* This block was found. Tidy up the mark. */ b->aux = NULL; else - deleted_handler |= flow_delete_block (b); + flow_delete_block (b); } tidy_fallthru_edges (); - /* If we deleted an exception handler, we may have EH region begin/end - blocks to remove as well. */ - if (deleted_handler) - delete_eh_regions (); - free (worklist); } -/* Find EH regions for which there is no longer a handler, and delete them. */ - -static void -delete_eh_regions () -{ - rtx insn; - - update_rethrow_references (); - - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (GET_CODE (insn) == NOTE) - { - if ((NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - || (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) - { - int num = NOTE_EH_HANDLER (insn); - /* A NULL handler indicates a region is no longer needed, - as long as its rethrow label isn't used. */ - if (get_first_handler (num) == NULL && ! rethrow_used (num)) - { - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - NOTE_SOURCE_FILE (insn) = 0; - } - } - } -} - /* Return true if NOTE is not one of the ones that must be kept paired, so that we may simply delete them. */ @@ -2387,26 +2192,7 @@ flow_delete_block (b) never_reached_warning (insn); if (GET_CODE (insn) == CODE_LABEL) - { - rtx x, *prev = &exception_handler_labels; - - for (x = exception_handler_labels; x; x = XEXP (x, 1)) - { - if (XEXP (x, 0) == insn) - { - /* Found a match, splice this label out of the EH label list. */ - *prev = XEXP (x, 1); - XEXP (x, 1) = NULL_RTX; - XEXP (x, 0) = NULL_RTX; - - /* Remove the handler from all regions */ - remove_handler (insn); - deleted_handler = 1; - break; - } - prev = &XEXP (x, 1); - } - } + maybe_remove_eh_handler (insn); /* Include any jump table following the basic block. */ end = b->end; @@ -2804,7 +2590,6 @@ merge_blocks (e, b, c) else { edge tmp_edge; - basic_block d; int c_has_outgoing_fallthru; int b_has_incoming_fallthru; @@ -2832,37 +2617,22 @@ merge_blocks (e, b, c) break; b_has_incoming_fallthru = (tmp_edge != NULL); - /* If B does not have an incoming fallthru, and the exception regions - match, then it can be moved immediately before C without introducing - or modifying jumps. - - C can not be the first block, so we do not have to worry about + /* If B does not have an incoming fallthru, then it can be moved + immediately before C without introducing or modifying jumps. + C cannot be the first block, so we do not have to worry about accessing a non-existent block. */ - d = BASIC_BLOCK (c->index - 1); - if (! b_has_incoming_fallthru - && d->eh_end == b->eh_beg - && b->eh_end == c->eh_beg) + if (! b_has_incoming_fallthru) return merge_blocks_move_predecessor_nojumps (b, c); - /* Otherwise, we're going to try to move C after B. Make sure the - exception regions match. + /* Otherwise, we're going to try to move C after B. If C does + not have an outgoing fallthru, then it can be moved + immediately after B without introducing or modifying jumps. */ + if (! c_has_outgoing_fallthru) + return merge_blocks_move_successor_nojumps (b, c); - If B is the last basic block, then we must not try to access the - block structure for block B + 1. Luckily in that case we do not - need to worry about matching exception regions. */ - d = (b->index + 1 < n_basic_blocks ? BASIC_BLOCK (b->index + 1) : NULL); - if (b->eh_end == c->eh_beg - && (d == NULL || c->eh_end == d->eh_beg)) - { - /* If C does not have an outgoing fallthru, then it can be moved - immediately after B without introducing or modifying jumps. */ - if (! c_has_outgoing_fallthru) - return merge_blocks_move_successor_nojumps (b, c); - - /* Otherwise, we'll need to insert an extra jump, and possibly - a new block to contain it. */ - /* ??? Not implemented yet. */ - } + /* Otherwise, we'll need to insert an extra jump, and possibly + a new block to contain it. */ + /* ??? Not implemented yet. */ return 0; } @@ -3502,14 +3272,44 @@ mark_regs_live_at_end (set) if (global_regs[i] || EPILOGUE_USES (i)) SET_REGNO_REG_SET (set, i); - /* Mark all call-saved registers that we actaully used. */ if (HAVE_epilogue && reload_completed) { + /* Mark all call-saved registers that we actually used. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (regs_ever_live[i] && ! call_used_regs[i] && ! LOCAL_REGNO (i)) SET_REGNO_REG_SET (set, i); } +#ifdef EH_RETURN_DATA_REGNO + /* Mark the registers that will contain data for the handler. */ + if (reload_completed && current_function_calls_eh_return) + for (i = 0; ; ++i) + { + unsigned regno = EH_RETURN_DATA_REGNO(i); + if (regno == INVALID_REGNUM) + break; + SET_REGNO_REG_SET (set, regno); + } +#endif +#ifdef EH_RETURN_STACKADJ_RTX + if ((! HAVE_epilogue || ! reload_completed) + && current_function_calls_eh_return) + { + rtx tmp = EH_RETURN_STACKADJ_RTX; + if (tmp && REG_P (tmp)) + mark_reg (tmp, set); + } +#endif +#ifdef EH_RETURN_HANDLER_RTX + if ((! HAVE_epilogue || ! reload_completed) + && current_function_calls_eh_return) + { + rtx tmp = EH_RETURN_HANDLER_RTX; + if (tmp && REG_P (tmp)) + mark_reg (tmp, set); + } +#endif + /* Mark function return value. */ diddle_return_value (mark_reg, set); } @@ -4249,7 +4049,8 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags) && (flags & PROP_SCAN_DEAD_CODE) && (bb->succ == NULL || (bb->succ->succ_next == NULL - && bb->succ->dest == EXIT_BLOCK_PTR))) + && bb->succ->dest == EXIT_BLOCK_PTR + && ! current_function_calls_eh_return))) { rtx insn, set; for (insn = bb->end; insn != bb->head; insn = PREV_INSN (insn)) @@ -6631,8 +6432,6 @@ dump_bb (bb, outf) fprintf (outf, ";; Basic block %d, loop depth %d, count %d", bb->index, bb->loop_depth, bb->count); - if (bb->eh_beg != -1 || bb->eh_end != -1) - fprintf (outf, ", eh regions %d/%d", bb->eh_beg, bb->eh_end); putc ('\n', outf); fputs (";; Predecessors: ", outf); diff --git a/gcc/frame-dwarf2.c b/gcc/frame-dwarf2.c deleted file mode 100644 index 7fbcf87c6c8..00000000000 --- a/gcc/frame-dwarf2.c +++ /dev/null @@ -1,778 +0,0 @@ -/* Subroutines needed for unwinding DWARF 2 format stack frame info - for exception handling. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - Contributed by Jason Merrill . - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file into combinations with other programs, -and to distribute those combinations without any restriction coming -from the use of this file. (The General Public License restrictions -do apply in other respects; for example, they cover modification of -the file, and distribution when not linked into a combine -executable.) - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* It is incorrect to include config.h here, because this file is being - compiled for the target, and hence definitions concerning only the host - do not apply. */ - -#include "tconfig.h" -#include "tsystem.h" - -#ifdef DWARF2_UNWIND_INFO -#include "dwarf2.h" -#include "frame.h" -#include "gthr.h" - -#ifdef __GTHREAD_MUTEX_INIT -static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; -#else -static __gthread_mutex_t object_mutex; -#endif - -/* Don't use `fancy_abort' here even if config.h says to use it. */ -#ifdef abort -#undef abort -#endif - -/* Some types used by the DWARF 2 spec. */ - -typedef int sword __attribute__ ((mode (SI))); -typedef unsigned int uword __attribute__ ((mode (SI))); -typedef unsigned int uaddr __attribute__ ((mode (pointer))); -typedef int saddr __attribute__ ((mode (pointer))); -typedef unsigned char ubyte; - -/* Terminology: - CIE - Common Information Element - FDE - Frame Descriptor Element - - There is one per function, and it describes where the function code - is located, and what the register lifetimes and stack layout are - within the function. - - The data structures are defined in the DWARF specfication, although - not in a very readable way (see LITERATURE). - - Every time an exception is thrown, the code needs to locate the FDE - for the current function, and starts to look for exception regions - from that FDE. This works in a two-level search: - a) in a linear search, find the shared image (i.e. DLL) containing - the PC - b) using the FDE table for that shared object, locate the FDE using - binary search (which requires the sorting). */ - -/* The first few fields of a CIE. The CIE_id field is 0 for a CIE, - to distinguish it from a valid FDE. FDEs are aligned to an addressing - unit boundary, but the fields within are unaligned. */ - -struct dwarf_cie { - uword length; - sword CIE_id; - ubyte version; - char augmentation[0]; -} __attribute__ ((packed, aligned (__alignof__ (void *)))); - -/* The first few fields of an FDE. */ - -struct dwarf_fde { - uword length; - sword CIE_delta; - void* pc_begin; - uaddr pc_range; -} __attribute__ ((packed, aligned (__alignof__ (void *)))); - -typedef struct dwarf_fde fde; - -/* Objects to be searched for frame unwind info. */ - -static struct object *objects; - -/* The information we care about from a CIE. */ - -struct cie_info { - char *augmentation; - void *eh_ptr; - int code_align; - int data_align; - unsigned ra_regno; -}; - -/* The current unwind state, plus a saved copy for DW_CFA_remember_state. */ - -struct frame_state_internal -{ - struct frame_state s; - struct frame_state_internal *saved_state; -}; - -/* This is undefined below if we need it to be an actual function. */ -#define init_object_mutex_once() - -#if __GTHREADS -#ifdef __GTHREAD_MUTEX_INIT_FUNCTION - -/* Helper for init_object_mutex_once. */ - -static void -init_object_mutex (void) -{ - __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex); -} - -/* Call this to arrange to initialize the object mutex. */ - -#undef init_object_mutex_once -static void -init_object_mutex_once (void) -{ - static __gthread_once_t once = __GTHREAD_ONCE_INIT; - __gthread_once (&once, init_object_mutex); -} - -#endif /* __GTHREAD_MUTEX_INIT_FUNCTION */ -#endif /* __GTHREADS */ - -/* Decode the unsigned LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. */ - -static void * -decode_uleb128 (unsigned char *buf, unsigned *r) -{ - unsigned shift = 0; - unsigned result = 0; - - while (1) - { - unsigned byte = *buf++; - result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - *r = result; - return buf; -} - -/* Decode the signed LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. */ - -static void * -decode_sleb128 (unsigned char *buf, int *r) -{ - unsigned shift = 0; - unsigned result = 0; - unsigned byte; - - while (1) - { - byte = *buf++; - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) - result |= - (1 << shift); - - *r = result; - return buf; -} - -/* Read unaligned data from the instruction buffer. */ - -union unaligned { - void *p; - unsigned b2 __attribute__ ((mode (HI))); - unsigned b4 __attribute__ ((mode (SI))); - unsigned b8 __attribute__ ((mode (DI))); -} __attribute__ ((packed)); -static inline void * -read_pointer (void *p) -{ union unaligned *up = p; return up->p; } -static inline unsigned -read_1byte (void *p) -{ return *(unsigned char *)p; } -static inline unsigned -read_2byte (void *p) -{ union unaligned *up = p; return up->b2; } -static inline unsigned -read_4byte (void *p) -{ union unaligned *up = p; return up->b4; } -static inline unsigned long -read_8byte (void *p) -{ union unaligned *up = p; return up->b8; } - -/* Ordering function for FDEs. Functions can't overlap, so we just compare - their starting addresses. */ - -static inline saddr -fde_compare (fde *x, fde *y) -{ - return (saddr)x->pc_begin - (saddr)y->pc_begin; -} - -/* Return the address of the FDE after P. */ - -static inline fde * -next_fde (fde *p) -{ - return (fde *)(((char *)p) + p->length + sizeof (p->length)); -} - -#include "frame.c" - -static size_t -count_fdes (fde *this_fde) -{ - size_t count; - - for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde)) - { - /* Skip CIEs and linked once FDE entries. */ - if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) - continue; - - ++count; - } - - return count; -} - -static void -add_fdes (fde *this_fde, fde_accumulator *accu, void **beg_ptr, void **end_ptr) -{ - void *pc_begin = *beg_ptr; - void *pc_end = *end_ptr; - - for (; this_fde->length != 0; this_fde = next_fde (this_fde)) - { - /* Skip CIEs and linked once FDE entries. */ - if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) - continue; - - fde_insert (accu, this_fde); - - if (this_fde->pc_begin < pc_begin) - pc_begin = this_fde->pc_begin; - if (this_fde->pc_begin + this_fde->pc_range > pc_end) - pc_end = this_fde->pc_begin + this_fde->pc_range; - } - - *beg_ptr = pc_begin; - *end_ptr = pc_end; -} - -/* search this fde table for the one containing the pc */ -static fde * -search_fdes (fde *this_fde, void *pc) -{ - for (; this_fde->length != 0; this_fde = next_fde (this_fde)) - { - /* Skip CIEs and linked once FDE entries. */ - if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) - continue; - - if ((uaddr)((char *)pc - (char *)this_fde->pc_begin) < this_fde->pc_range) - return this_fde; - } - return NULL; -} - -/* Set up a sorted array of pointers to FDEs for a loaded object. We - count up the entries before allocating the array because it's likely to - be faster. We can be called multiple times, should we have failed to - allocate a sorted fde array on a previous occasion. */ - -static void -frame_init (struct object* ob) -{ - size_t count; - fde_accumulator accu; - void *pc_begin, *pc_end; - fde **array; - - if (ob->pc_begin) - count = ob->count; - else if (ob->fde_array) - { - fde **p = ob->fde_array; - for (count = 0; *p; ++p) - count += count_fdes (*p); - } - else - count = count_fdes (ob->fde_begin); - ob->count = count; - - if (!start_fde_sort (&accu, count) && ob->pc_begin) - return; - - pc_begin = (void*)(uaddr)-1; - pc_end = 0; - - if (ob->fde_array) - { - fde **p = ob->fde_array; - for (; *p; ++p) - add_fdes (*p, &accu, &pc_begin, &pc_end); - } - else - add_fdes (ob->fde_begin, &accu, &pc_begin, &pc_end); - - array = end_fde_sort (&accu, count); - if (array) - ob->fde_array = array; - ob->pc_begin = pc_begin; - ob->pc_end = pc_end; -} - -/* Return a pointer to the FDE for the function containing PC. */ - -static fde * -find_fde (void *pc) -{ - struct object *ob; - size_t lo, hi; - - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); - - /* Linear search through the objects, to find the one containing the pc. */ - for (ob = objects; ob; ob = ob->next) - { - if (ob->pc_begin == 0) - frame_init (ob); - if (pc >= ob->pc_begin && pc < ob->pc_end) - break; - } - - if (ob == 0) - { - __gthread_mutex_unlock (&object_mutex); - return 0; - } - - if (!ob->fde_array || (void *)ob->fde_array == (void *)ob->fde_begin) - frame_init (ob); - - if (ob->fde_array && (void *)ob->fde_array != (void *)ob->fde_begin) - { - __gthread_mutex_unlock (&object_mutex); - - /* Standard binary search algorithm. */ - for (lo = 0, hi = ob->count; lo < hi; ) - { - size_t i = (lo + hi) / 2; - fde *f = ob->fde_array[i]; - - if (pc < f->pc_begin) - hi = i; - else if (pc >= f->pc_begin + f->pc_range) - lo = i + 1; - else - return f; - } - } - else - { - /* Long slow labourious linear search, cos we've no memory. */ - fde *f; - - if (ob->fde_array) - { - fde **p = ob->fde_array; - - do - { - f = search_fdes (*p, pc); - if (f) - break; - p++; - } - while (*p); - } - else - f = search_fdes (ob->fde_begin, pc); - __gthread_mutex_unlock (&object_mutex); - return f; - } - return 0; -} - -static inline struct dwarf_cie * -get_cie (fde *f) -{ - return ((void *)&f->CIE_delta) - f->CIE_delta; -} - -/* Extract any interesting information from the CIE for the translation - unit F belongs to. */ - -static void * -extract_cie_info (fde *f, struct cie_info *c) -{ - void *p; - int i; - - c->augmentation = get_cie (f)->augmentation; - - if (strcmp (c->augmentation, "") != 0 - && strcmp (c->augmentation, "eh") != 0 - && c->augmentation[0] != 'z') - return 0; - - p = c->augmentation + strlen (c->augmentation) + 1; - - if (strcmp (c->augmentation, "eh") == 0) - { - c->eh_ptr = read_pointer (p); - p += sizeof (void *); - } - else - c->eh_ptr = 0; - - p = decode_uleb128 (p, &c->code_align); - p = decode_sleb128 (p, &c->data_align); - c->ra_regno = *(unsigned char *)p++; - - /* If the augmentation starts with 'z', we now see the length of the - augmentation fields. */ - if (c->augmentation[0] == 'z') - { - p = decode_uleb128 (p, &i); - p += i; - } - - return p; -} - -/* Decode a DW_OP stack operation. */ - -static void * -decode_stack_op (unsigned char *buf, struct frame_state *state) -{ - enum dwarf_location_atom op; - int offset; - - op = *buf++; - switch (op) - { - case DW_OP_reg0: - case DW_OP_reg1: - case DW_OP_reg2: - case DW_OP_reg3: - case DW_OP_reg4: - case DW_OP_reg5: - case DW_OP_reg6: - case DW_OP_reg7: - case DW_OP_reg8: - case DW_OP_reg9: - case DW_OP_reg10: - case DW_OP_reg11: - case DW_OP_reg12: - case DW_OP_reg13: - case DW_OP_reg14: - case DW_OP_reg15: - case DW_OP_reg16: - case DW_OP_reg17: - case DW_OP_reg18: - case DW_OP_reg19: - case DW_OP_reg20: - case DW_OP_reg21: - case DW_OP_reg22: - case DW_OP_reg23: - case DW_OP_reg24: - case DW_OP_reg25: - case DW_OP_reg26: - case DW_OP_reg27: - case DW_OP_reg28: - case DW_OP_reg29: - case DW_OP_reg30: - case DW_OP_reg31: - state->cfa_reg = op - DW_OP_reg0; - break; - case DW_OP_regx: - buf = decode_sleb128 (buf, &offset); - state->cfa_reg = offset; - break; - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: - state->cfa_reg = op - DW_OP_breg0; - buf = decode_sleb128 (buf, &offset); - state->base_offset = offset; - break; - case DW_OP_bregx: - buf = decode_sleb128 (buf, &offset); - state->cfa_reg = offset; - buf = decode_sleb128 (buf, &offset); - state->base_offset = offset; - break; - case DW_OP_deref: - state->indirect = 1; - break; - case DW_OP_plus_uconst: - buf = decode_uleb128 (buf, &offset); - state->cfa_offset = offset; - break; - default: - abort (); - } - return buf; -} -/* Decode one instruction's worth of DWARF 2 call frame information. - Used by __frame_state_for. Takes pointers P to the instruction to - decode, STATE to the current register unwind information, INFO to the - current CIE information, and PC to the current PC value. Returns a - pointer to the next instruction. */ - -static void * -execute_cfa_insn (void *p, struct frame_state_internal *state, - struct cie_info *info, void **pc) -{ - unsigned insn = *(unsigned char *)p++; - unsigned reg; - int offset; - - if (insn & DW_CFA_advance_loc) - *pc += ((insn & 0x3f) * info->code_align); - else if (insn & DW_CFA_offset) - { - reg = (insn & 0x3f); - p = decode_uleb128 (p, &offset); - if (reg == state->s.cfa_reg) - /* Don't record anything about this register; it's only used to - reload SP in the epilogue. We don't want to copy in SP - values for outer frames; we handle restoring SP specially. */; - else - { - offset *= info->data_align; - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = offset; - } - } - else if (insn & DW_CFA_restore) - { - reg = (insn & 0x3f); - state->s.saved[reg] = REG_UNSAVED; - } - else switch (insn) - { - case DW_CFA_set_loc: - *pc = read_pointer (p); - p += sizeof (void *); - break; - case DW_CFA_advance_loc1: - *pc += read_1byte (p); - p += 1; - break; - case DW_CFA_advance_loc2: - *pc += read_2byte (p); - p += 2; - break; - case DW_CFA_advance_loc4: - *pc += read_4byte (p); - p += 4; - break; - - case DW_CFA_offset_extended: - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, &offset); - if (reg == state->s.cfa_reg) - /* Don't record anything; see above. */; - else - { - offset *= info->data_align; - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = offset; - } - break; - case DW_CFA_restore_extended: - p = decode_uleb128 (p, ®); - state->s.saved[reg] = REG_UNSAVED; - break; - - case DW_CFA_undefined: - case DW_CFA_same_value: - case DW_CFA_nop: - break; - - case DW_CFA_register: - { - unsigned reg2; - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, ®2); - state->s.saved[reg] = REG_SAVED_REG; - state->s.reg_or_offset[reg] = reg2; - } - break; - - case DW_CFA_def_cfa: - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, &offset); - state->s.cfa_reg = reg; - state->s.cfa_offset = offset; - break; - case DW_CFA_def_cfa_register: - p = decode_uleb128 (p, ®); - state->s.cfa_reg = reg; - break; - case DW_CFA_def_cfa_offset: - p = decode_uleb128 (p, &offset); - state->s.cfa_offset = offset; - break; - case DW_CFA_def_cfa_expression: - { - void *end; - state->s.cfa_reg = 0; - state->s.cfa_offset = 0; - state->s.base_offset = 0; - state->s.indirect = 0; - - p = decode_uleb128 (p, &offset); - end = p + offset; - while (p < end) - p = decode_stack_op (p, &(state->s)); - break; - } - - case DW_CFA_remember_state: - { - struct frame_state_internal *save = - (struct frame_state_internal *) - malloc (sizeof (struct frame_state_internal)); - memcpy (save, state, sizeof (struct frame_state_internal)); - state->saved_state = save; - } - break; - case DW_CFA_restore_state: - { - struct frame_state_internal *save = state->saved_state; - memcpy (state, save, sizeof (struct frame_state_internal)); - free (save); - } - break; - - /* FIXME: Hardcoded for SPARC register window configuration. */ - case DW_CFA_GNU_window_save: - for (reg = 16; reg < 32; ++reg) - { - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *); - } - break; - - case DW_CFA_GNU_args_size: - p = decode_uleb128 (p, &offset); - state->s.args_size = offset; - break; - - case DW_CFA_GNU_negative_offset_extended: - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, &offset); - offset *= info->data_align; - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = -offset; - break; - - default: - abort (); - } - return p; -} - -/* Called from __throw to find the registers to restore for a given - PC_TARGET. The caller should allocate a local variable of `struct - frame_state' (declared in frame.h) and pass its address to STATE_IN. */ - -struct frame_state * -__frame_state_for (void *pc_target, struct frame_state *state_in) -{ - fde *f; - void *insn, *end, *pc; - struct cie_info info; - struct frame_state_internal state; - - f = find_fde (pc_target); - if (f == 0) - return 0; - - insn = extract_cie_info (f, &info); - if (insn == 0) - return 0; - - memset (&state, 0, sizeof (state)); - state.s.retaddr_column = info.ra_regno; - state.s.eh_ptr = info.eh_ptr; - - /* First decode all the insns in the CIE. */ - end = next_fde ((fde*) get_cie (f)); - while (insn < end) - insn = execute_cfa_insn (insn, &state, &info, 0); - - insn = ((fde *)f) + 1; - - if (info.augmentation[0] == 'z') - { - int i; - insn = decode_uleb128 (insn, &i); - insn += i; - } - - /* Then the insns in the FDE up to our target PC. */ - end = next_fde (f); - pc = f->pc_begin; - while (insn < end && pc <= pc_target) - insn = execute_cfa_insn (insn, &state, &info, &pc); - - memcpy (state_in, &state.s, sizeof (state.s)); - return state_in; -} -#endif /* DWARF2_UNWIND_INFO */ diff --git a/gcc/frame.h b/gcc/frame.h deleted file mode 100644 index 2257d5256c5..00000000000 --- a/gcc/frame.h +++ /dev/null @@ -1,287 +0,0 @@ -/* Header file for unwinding stack frames for exception handling. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - Contributed by Jason Merrill . - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#ifndef DWARF_FRAME_REGISTERS -#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER -#endif - -typedef struct frame_state -{ - void *cfa; - void *eh_ptr; - long cfa_offset; - long args_size; - long reg_or_offset[DWARF_FRAME_REGISTERS+1]; - unsigned short cfa_reg; - unsigned short retaddr_column; - char saved[DWARF_FRAME_REGISTERS+1]; - long base_offset; - char indirect; -} frame_state; - -/* Values for 'saved' above. */ -#define REG_UNSAVED 0 -#define REG_SAVED_OFFSET 1 -#define REG_SAVED_REG 2 - -/* The representation for an "object" to be searched for frame unwind info. - For targets with named sections, one object is an executable or shared - library; for other targets, one object is one translation unit. - - A copy of this structure declaration is printed by collect2.c; - keep the copies synchronized! */ - -struct object { -#ifdef IA64_UNWIND_INFO - void *pc_base; /* This field will be set by find_fde. */ -#endif - void *pc_begin; - void *pc_end; - struct dwarf_fde *fde_begin; -#ifdef IA64_UNWIND_INFO - struct dwarf_fde *fde_end; -#endif - struct dwarf_fde **fde_array; - size_t count; - struct object *next; -}; - -/* Note the following routines are exported interfaces from libgcc; do not - change these interfaces. Instead create new interfaces. Also note - references to these functions may be made weak in files where they - are referenced. */ - -extern void __register_frame (void * ); -extern void __register_frame_table (void *); -extern void __deregister_frame (void *); - -/* Called either from crtbegin.o or a static constructor to register the - unwind info for an object or translation unit, respectively. */ - -extern void __register_frame_info (void *, struct object *); - -/* Similar, but BEGIN is actually a pointer to a table of unwind entries - for different translation units. Called from the file generated by - collect2. */ -extern void __register_frame_info_table (void *, struct object *); - -/* Called from crtend.o to deregister the unwind info for an object. */ - -extern void *__deregister_frame_info (void *); - -/* Called from __throw to find the registers to restore for a given - PC_TARGET. The caller should allocate a local variable of `struct - frame_state' (declared in frame.h) and pass its address to STATE_IN. - Returns NULL on failure, otherwise returns STATE_IN. */ - -extern struct frame_state *__frame_state_for (void *, struct frame_state *); - -#ifdef IA64_UNWIND_INFO - -/* This is the information required for unwind records in an ia64 - object file. This is required by GAS and the compiler runtime. */ - -/* These are the starting point masks for the various types of - unwind records. To create a record of type R3 for instance, one - starts by using the value UNW_R3 and or-ing in any other required values. - These values are also unique (in context), so they can be used to identify - the various record types as well. UNW_Bx and some UNW_Px do have the - same value, but Px can only occur in a prologue context, and Bx in - a body context. */ - -#define UNW_R1 0x00 -#define UNW_R2 0x40 -#define UNW_R3 0x60 -#define UNW_P1 0x80 -#define UNW_P2 0xA0 -#define UNW_P3 0xB0 -#define UNW_P4 0xB8 -#define UNW_P5 0xB9 -#define UNW_P6 0xC0 -#define UNW_P7 0xE0 -#define UNW_P8 0xF0 -#define UNW_P9 0xF1 -#define UNW_P10 0xFF -#define UNW_X1 0xF9 -#define UNW_X2 0xFA -#define UNW_X3 0xFB -#define UNW_X4 0xFC -#define UNW_B1 0x80 -#define UNW_B2 0xC0 -#define UNW_B3 0xE0 -#define UNW_B4 0xF0 - -/* These are all the various types of unwind records. */ - -typedef enum -{ - prologue, prologue_gr, body, mem_stack_f, mem_stack_v, psp_gr, psp_sprel, - rp_when, rp_gr, rp_br, rp_psprel, rp_sprel, pfs_when, pfs_gr, pfs_psprel, - pfs_sprel, preds_when, preds_gr, preds_psprel, preds_sprel, - fr_mem, frgr_mem, gr_gr, gr_mem, br_mem, br_gr, spill_base, spill_mask, - unat_when, unat_gr, unat_psprel, unat_sprel, lc_when, lc_gr, lc_psprel, - lc_sprel, fpsr_when, fpsr_gr, fpsr_psprel, fpsr_sprel, - priunat_when_gr, priunat_when_mem, priunat_gr, priunat_psprel, - priunat_sprel, bsp_when, bsp_gr, bsp_psprel, bsp_sprel, bspstore_when, - bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr, - rnat_psprel, rnat_sprel, epilogue, label_state, copy_state, - spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p, - spill_reg_p -} unw_record_type; - - -/* These structures declare the fields that can be used in each of the - 4 record formats, R, P, B and X. */ - -typedef struct unw_r_record -{ - unsigned long rlen; - unsigned short mask; - unsigned short grsave; -} unw_r_record; - -typedef struct unw_p_record -{ - void *imask; - unsigned long t; - unsigned long size; - unsigned long spoff; - unsigned long br; - unsigned long pspoff; - unsigned short gr; - unsigned short rmask; - unsigned short grmask; - unsigned long frmask; - unsigned short brmask; -} unw_p_record; - -typedef struct unw_b_record -{ - unsigned long t; - unsigned long label; - unsigned short ecount; -} unw_b_record; - -typedef struct unw_x_record -{ - unsigned long t; - unsigned long spoff; - unsigned long pspoff; - unsigned short reg; - unsigned short treg; - unsigned short qp; - unsigned short xy; /* Value of the XY field.. */ -} unw_x_record; - -/* This structure is used to determine the specific record type and - its fields. */ -typedef struct unwind_record -{ - unw_record_type type; - union { - unw_r_record r; - unw_p_record p; - unw_b_record b; - unw_x_record x; - } record; -} unwind_record; - -#define IA64_UNW_LOC_TYPE_NONE 0 -#define IA64_UNW_LOC_TYPE_MEM 1 -#define IA64_UNW_LOC_TYPE_GR 2 -#define IA64_UNW_LOC_TYPE_FR 3 -#define IA64_UNW_LOC_TYPE_BR 4 -#define IA64_UNW_LOC_TYPE_SPOFF 5 -#define IA64_UNW_LOC_TYPE_PSPOFF 6 -#define IA64_UNW_LOC_TYPE_OFFSET 7 -#define IA64_UNW_LOC_TYPE_SPILLBASE 8 - -typedef struct ia64_reg_loc -{ - long when; /* PC relative offset from start of function. */ - union { /* In memory or another register? */ - void *mem; - int regno; - int offset; - } l; - short loc_type; /* Where to find value. */ - short reg_size; -} ia64_reg_loc; - -/* Frame information record. */ - -typedef struct ia64_frame_state -{ - ia64_reg_loc gr[4]; /* gr4 to gr7. */ - ia64_reg_loc fr[20]; /* fr2 to fr5, fr16 to fr31. */ - ia64_reg_loc br[5]; /* br1 to br5. */ - ia64_reg_loc rp; - ia64_reg_loc fpsr; - ia64_reg_loc bsp; - ia64_reg_loc bspstore; - ia64_reg_loc rnat; - ia64_reg_loc pfs; - ia64_reg_loc unat; - ia64_reg_loc lc; - ia64_reg_loc pr; - ia64_reg_loc priunat; - ia64_reg_loc sp; - ia64_reg_loc psp; - ia64_reg_loc spill_base; - void *my_psp; - void *my_sp; - void *my_bsp; -} ia64_frame_state; - -/* This structure represents the start of an unwind information pointer. - 'unwind_descriptors' is the beginninng of the unwind descriptors, which - use up 'length' bytes of storage. */ - -typedef struct unwind_info_ptr -{ - unsigned long header; /* version, flags, & length */ - unsigned char unwind_descriptors[1]; -} unwind_info_ptr; - -#define IA64_UNW_HDR_LENGTH(x) ((x) & 0x00000000ffffffffUL) -#define IA64_UNW_HDR_FLAGS(x) (((x) >> 32) & 0xffffUL) -#define IA64_UNW_HDR_VERSION(x) (((x) >> 48) & 0xffffUL) - -/* Header flag bits, after extraction by IA64_UNW_HDR_FLAGS. */ -#define IA64_UNW_EHANDLER 0x1 -#define IA64_UNW_UHANDLER 0x2 - -extern void * __ia64_personality_v1 (void *pc, old_exception_table *table); - -extern unwind_info_ptr *__build_ia64_frame_state (unsigned char *, - ia64_frame_state *, - void *, void *, - void **); -extern void *__get_real_reg_value (ia64_reg_loc *); -extern void *__get_personality (unwind_info_ptr *); -extern void *__get_except_table (unwind_info_ptr *); -extern void __set_real_reg_value (ia64_reg_loc *, void *); -void *__calc_caller_bsp (long, unsigned char *); -void __copy_saved_reg_state (ia64_frame_state *, ia64_frame_state *); -#endif /* IA64_UNWIND_INFO */ - diff --git a/gcc/function.c b/gcc/function.c index 71bdf9d6766..6eebf34f284 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1580,11 +1580,6 @@ fixup_var_refs (var, promoted_mode, unsignedp, ht) end_sequence (); } } - - /* Scan the catch clauses for exception handling too. */ - push_to_full_sequence (catch_clauses, catch_clauses_last); - fixup_var_refs_insns (catch_clauses, var, promoted_mode, unsignedp, 0); - end_full_sequence (&catch_clauses, &catch_clauses_last); } /* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is @@ -6315,20 +6310,10 @@ expand_function_start (subr, parms_have_cleanups) else cleanup_label = 0; - /* Make the label for return statements to jump to, if this machine - does not have a one-instruction return and uses an epilogue, - or if it returns a structure, or if it has parm cleanups. */ -#ifdef HAVE_return - if (cleanup_label == 0 && HAVE_return - && ! current_function_instrument_entry_exit - && ! current_function_returns_pcc_struct - && ! (current_function_returns_struct && ! optimize)) - return_label = 0; - else - return_label = gen_label_rtx (); -#else + /* Make the label for return statements to jump to. Do not special + case machines with special return instructions -- they will be + handled later during jump, ifcvt, or epilogue creation. */ return_label = gen_label_rtx (); -#endif /* Initialize rtx used to return the value. */ /* Do this before assign_parms so that we copy the struct value address @@ -6370,7 +6355,9 @@ expand_function_start (subr, parms_have_cleanups) else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode) /* If return mode is void, this decl rtl should not be used. */ SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX); - else if (parms_have_cleanups || current_function_instrument_entry_exit) + else if (parms_have_cleanups + || current_function_instrument_entry_exit + || (flag_exceptions && USING_SJLJ_EXCEPTIONS)) { /* If function will end with cleanup code for parms, compute the return values into a pseudo reg, @@ -6801,27 +6788,6 @@ expand_function_end (filename, line, end_bindings) if (end_bindings) expand_end_bindings (0, 0, 0); - /* Now handle any leftover exception regions that may have been - created for the parameters. */ - { - rtx last = get_last_insn (); - rtx label; - - expand_leftover_cleanups (); - - /* If there are any catch_clauses remaining, output them now. */ - emit_insns (catch_clauses); - catch_clauses = catch_clauses_last = NULL_RTX; - /* If the above emitted any code, may sure we jump around it. */ - if (last != get_last_insn ()) - { - label = gen_label_rtx (); - last = emit_jump_insn_after (gen_jump (label), last); - last = emit_barrier_after (last); - emit_label (label); - } - } - if (current_function_instrument_entry_exit) { rtx fun = DECL_RTL (current_function_decl); @@ -6837,6 +6803,11 @@ expand_function_end (filename, line, end_bindings) Pmode); } + /* Let except.c know where it should emit the call to unregister + the function context for sjlj exceptions. */ + if (flag_exceptions && USING_SJLJ_EXCEPTIONS) + sjlj_emit_function_exit_after (get_last_insn ()); + /* If we had calls to alloca, and this machine needs an accurate stack pointer to exit the function, insert some code to save and restore the stack pointer. */ @@ -6944,16 +6915,16 @@ expand_function_end (filename, line, end_bindings) current_function_return_rtx = outgoing; } + /* If this is an implementation of throw, do what's necessary to + communicate between __builtin_eh_return and the epilogue. */ + expand_eh_return (); + /* ??? This should no longer be necessary since stupid is no longer with us, but there are some parts of the compiler (eg reload_combine, and sh mach_dep_reorg) that still try and compute their own lifetime info instead of using the general framework. */ use_return_register (); - /* If this is an implementation of __throw, do what's necessary to - communicate between __builtin_eh_return and the epilogue. */ - expand_eh_return (); - /* Output a return insn if we are using one. Otherwise, let the rtl chain end here, to drop through into the epilogue. */ diff --git a/gcc/function.h b/gcc/function.h index bd4f38ca0aa..5621c6b581d 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -409,6 +409,9 @@ struct function either as a subroutine or builtin. */ unsigned int calls_alloca : 1; + /* Nonzero if the function calls __builtin_eh_return. */ + unsigned int calls_eh_return : 1; + /* Nonzero if function being compiled receives nonlocal gotos from nested functions. */ unsigned int has_nonlocal_label : 1; @@ -488,6 +491,7 @@ extern struct function *all_functions; #define current_function_calls_setjmp (cfun->calls_setjmp) #define current_function_calls_alloca (cfun->calls_alloca) #define current_function_calls_longjmp (cfun->calls_longjmp) +#define current_function_calls_eh_return (cfun->calls_eh_return) #define current_function_has_computed_jump (cfun->has_computed_jump) #define current_function_contains_functions (cfun->contains_functions) #define current_function_is_thunk (cfun->is_thunk) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index d21cb4daf49..32971074939 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1905,7 +1905,7 @@ find_if_block (test_bb, then_edge, else_edge) /* Make sure IF, THEN, and ELSE, blocks are adjacent. Actually, we get the first condition for free, since we've already asserted that there's a fallthru edge from IF to THEN. */ - /* ??? As an enhancement, move the ELSE block. Have to deal with EH and + /* ??? As an enhancement, move the ELSE block. Have to deal with BLOCK notes, if by no other means than aborting the merge if they exist. Sticky enough I don't want to think about it now. */ next_index = then_bb->index; @@ -2188,15 +2188,6 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep) { rtx head, end, jump, earliest, old_dest; - /* No code movement can occur if we'd be scrogging EH regions. - Within MERGE_BB, ensure that we've not got stray EH_BEG or EH_END - notes within the block. Between the blocks, checking that the end - region numbers match ensures that we won't disrupt the nesting - between regions. */ - if (merge_bb->eh_beg != merge_bb->eh_end - || merge_bb->eh_end != test_bb->eh_end) - return FALSE; - jump = test_bb->end; /* Find the extent of the real code in the merge block. */ diff --git a/gcc/integrate.c b/gcc/integrate.c index bedfd149610..ed6540e4bfd 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -81,12 +81,12 @@ static void set_block_abstract_flags PARAMS ((tree, int)); static void process_reg_param PARAMS ((struct inline_remap *, rtx, rtx)); void set_decl_abstract_flags PARAMS ((tree, int)); -static rtx expand_inline_function_eh_labelmap PARAMS ((rtx)); static void mark_stores PARAMS ((rtx, rtx, void *)); static void save_parm_insns PARAMS ((rtx, rtx)); static void copy_insn_list PARAMS ((rtx, struct inline_remap *, rtx)); -static void copy_insn_notes PARAMS ((rtx, struct inline_remap *)); +static void copy_insn_notes PARAMS ((rtx, struct inline_remap *, + int)); static int compare_blocks PARAMS ((const PTR, const PTR)); static int find_block PARAMS ((const PTR, const PTR)); @@ -152,6 +152,9 @@ function_cannot_inline_p (fndecl) if (current_function_calls_setjmp) return N_("function using setjmp cannot be inline"); + if (current_function_calls_eh_return) + return N_("function uses __builtin_eh_return"); + if (current_function_contains_functions) return N_("function with nested functions cannot be inline"); @@ -221,19 +224,6 @@ function_cannot_inline_p (fndecl) if (current_function_has_nonlocal_goto) return N_("function with nonlocal goto cannot be inline"); - /* This is a hack, until the inliner is taught about eh regions at - the start of the function. */ - for (insn = get_insns (); - insn - && ! (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG); - insn = NEXT_INSN (insn)) - { - if (insn && GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) - return N_("function with complex parameters cannot be inline"); - } - /* We can't inline functions that return a PARALLEL rtx. */ if (DECL_RTL_SET_P (DECL_RESULT (fndecl))) { @@ -548,17 +538,6 @@ process_reg_param (map, loc, copy) map->reg_map[REGNO (loc)] = copy; } -/* Used by duplicate_eh_handlers to map labels for the exception table */ -static struct inline_remap *eif_eh_map; - -static rtx -expand_inline_function_eh_labelmap (label) - rtx label; -{ - int index = CODE_LABEL_NUMBER (label); - return get_label_from_map (eif_eh_map, index); -} - /* Compare two BLOCKs for qsort. The key we sort on is the BLOCK_ABSTRACT_ORIGIN of the blocks. */ @@ -634,6 +613,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, rtvec arg_vector = (rtvec) inl_f->original_arg_vector; rtx static_chain_value = 0; int inl_max_uid; + int eh_region_offset; /* The pointer used to track the true location of the memory used for MAP->LABEL_MAP. */ @@ -1140,8 +1120,14 @@ expand_inline_function (fndecl, parms, target, ignore, type, /* Now copy the insns one by one. */ copy_insn_list (insns, map, static_chain_value); + /* Duplicate the EH regions. This will create an offset from the + region numbers in the function we're inlining to the region + numbers in the calling function. This must wait until after + copy_insn_list, as we need the insn map to be complete. */ + eh_region_offset = duplicate_eh_regions (inl_f, map); + /* Now copy the REG_NOTES for those insns. */ - copy_insn_notes (insns, map); + copy_insn_notes (insns, map, eh_region_offset); /* If the insn sequence required one, emit the return label. */ if (map->local_return_label) @@ -1260,12 +1246,6 @@ copy_insn_list (insns, map, static_chain_value) inline_target. */ break; - /* If the inline fn needs eh context, make sure that - the current fn has one. */ - if (GET_CODE (pattern) == USE - && find_reg_note (insn, REG_EH_CONTEXT, 0) != 0) - get_eh_context (); - /* Ignore setting a function value that we don't want to use. */ if (map->inline_target == 0 && set != 0 @@ -1526,31 +1506,9 @@ copy_insn_list (insns, map, static_chain_value) copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn)); if (copy - && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG - || NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_END)) - { - rtx label - = get_label_from_map (map, NOTE_EH_HANDLER (copy)); - - /* We have to duplicate the handlers for the original. */ - if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG) - { - /* We need to duplicate the handlers for the EH region - and we need to indicate where the label map is */ - eif_eh_map = map; - duplicate_eh_handlers (NOTE_EH_HANDLER (copy), - CODE_LABEL_NUMBER (label), - expand_inline_function_eh_labelmap); - } - - /* We have to forward these both to match the new exception - region. */ - NOTE_EH_HANDLER (copy) = CODE_LABEL_NUMBER (label); - } - else if (copy - && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG - || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END) - && NOTE_BLOCK (insn)) + && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG + || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END) + && NOTE_BLOCK (insn)) { tree *mapped_block_p; @@ -1587,9 +1545,10 @@ copy_insn_list (insns, map, static_chain_value) that are valid across the entire function. */ static void -copy_insn_notes (insns, map) +copy_insn_notes (insns, map, eh_region_offset) rtx insns; struct inline_remap *map; + int eh_region_offset; { rtx insn, new_insn; @@ -1620,6 +1579,9 @@ copy_insn_notes (insns, map) next = XEXP (note, 1); if (REG_NOTE_KIND (note) == REG_LABEL) remove_note (new_insn, note); + else if (REG_NOTE_KIND (note) == REG_EH_REGION) + XEXP (note, 0) = GEN_INT (INTVAL (XEXP (note, 0)) + + eh_region_offset); } } @@ -1628,8 +1590,12 @@ copy_insn_notes (insns, map) { int i; for (i = 0; i < 3; i++) - copy_insn_notes (XEXP (PATTERN (insn), i), map); + copy_insn_notes (XEXP (PATTERN (insn), i), map, eh_region_offset); } + + if (GET_CODE (insn) == JUMP_INSN + && GET_CODE (PATTERN (insn)) == RESX) + XINT (PATTERN (new_insn), 0) += eh_region_offset; } } @@ -2071,12 +2037,6 @@ copy_rtx_and_substitute (orig, map, for_lhs) copy_rtx_and_substitute (constant, map, for_lhs)), 0); } - else if (SYMBOL_REF_NEED_ADJUST (orig)) - { - eif_eh_map = map; - return rethrow_symbol_map (orig, - expand_inline_function_eh_labelmap); - } return orig; diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 8ccb4b29d03..48dc795d4d5 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,34 @@ +2001-03-28 Richard Henderson + + IA-64 ABI Exception Handling: + * Make-lang.in (except.o): Don't depend on eh-common.h. + * check-init.c (check_init): Handle EXC_PTR_EXPR. + * decl.c (init_decl_processing) [throw_node]: No _Jv_Sjlj_Throw. + [soft_exceptioninfo_call_node]: Remove. + [eh_personality_libfunc, lang_eh_runtime_type]: New. + (end_java_method): No emit_handlers. + * except.c (java_set_exception_lang_code): Remove. + (method_init_exceptions): Don't call it. + (prepare_eh_table_type): No CATCH_ALL_TYPE. + (build_exception_object_ref): New. + (expand_end_java_handler): Update for except.h name changes. + (emit_handlers, expand_resume_after_catch): Remove. + * expr.c (java_lang_expand_expr): Update for except.h name changes. + (process_jvm_instruction): Use build_exception_object_ref. + * java-tree.h (JTI_SOFT_EXCEPTIONINFO_CALL_NODE): Remove. + (soft_exceptioninfo_call_node): Remove. + (build_exception_object_ref): Declare. + * jcf-write.c (generate_bytecode_insns) [CALL_EXPR]: No + soft_exceptioninfo_call_node. Move processing ... + [EXC_PTR_EXPR]: ... here. + * parse.h (BUILD_ASSIGN_EXCEPTION_INFO): Remove dead code. + * parse.y (catch_clause_parameter): Use build_exception_object_ref. + (source_end_java_method): No java_set_exception_lang_code or + emit_handlers. + (build_dot_class_method): Use build_exception_object_ref. + (try_reference_assignconv): Check EXC_PTR_EXPR not + soft_exceptioninfo_call_node. + 2001-03-28 Richard Henderson * java-tree.h (throw_node): Define as a single member of diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in index a4f5e481307..ebfbd73896d 100644 --- a/gcc/java/Make-lang.in +++ b/gcc/java/Make-lang.in @@ -254,7 +254,7 @@ java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \ toplev.h $(SYSTEM_H) function.h gcc.h java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \ $(RTL_H) java/javaop.h java/java-opcodes.h except.h java/java-except.h \ - eh-common.h toplev.h $(SYSTEM_H) function.h + toplev.h $(SYSTEM_H) function.h java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \ $(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \ java/java-except.h java/java-except.h java/parse.h toplev.h \ diff --git a/gcc/java/check-init.c b/gcc/java/check-init.c index 74144020afb..c34822084ec 100644 --- a/gcc/java/check-init.c +++ b/gcc/java/check-init.c @@ -681,6 +681,7 @@ check_init (exp, before) case INTEGER_CST: case REAL_CST: case STRING_CST: + case EXC_PTR_EXPR: break; case NEW_CLASS_EXPR: diff --git a/gcc/java/decl.c b/gcc/java/decl.c index c0b67b22d7c..7d03f8a4f3e 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -29,12 +29,14 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "config.h" #include "system.h" #include "tree.h" +#include "rtl.h" #include "toplev.h" #include "flags.h" #include "java-tree.h" #include "jcf.h" #include "toplev.h" #include "function.h" +#include "expr.h" #include "except.h" #include "java-except.h" #include "ggc.h" @@ -725,13 +727,14 @@ init_decl_processing () t), 0, NOT_BUILT_IN, NULL_PTR); - throw_node = builtin_function ((USING_SJLJ_EXCEPTIONS - ? "_Jv_Throw" : "_Jv_Sjlj_Throw"), + + throw_node = builtin_function ("_Jv_Throw", build_function_type (ptr_type_node, t), 0, NOT_BUILT_IN, NULL_PTR); /* Mark throw_nodes as `noreturn' functions with side effects. */ TREE_THIS_VOLATILE (throw_node) = 1; TREE_SIDE_EFFECTS (throw_node) = 1; + t = build_function_type (int_type_node, endlink); soft_monitorenter_node = builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN, @@ -834,15 +837,6 @@ init_decl_processing () build_function_type (double_type_node, t), BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmod"); - soft_exceptioninfo_call_node - = build (CALL_EXPR, - ptr_type_node, - build_address_of - (builtin_function ("_Jv_exception_info", - build_function_type (ptr_type_node, endlink), - 0, NOT_BUILT_IN, NULL_PTR)), - NULL_TREE, NULL_TREE); - TREE_SIDE_EFFECTS (soft_exceptioninfo_call_node) = 1; #if 0 t = tree_cons (NULL_TREE, float_type_node, tree_cons (NULL_TREE, float_type_node, endlink)); @@ -872,6 +866,12 @@ init_decl_processing () build_function_type (long_type_node, t), 0, NOT_BUILT_IN, NULL_PTR); + /* Initialize variables for except.c. */ + eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS + ? "__gcj_personality_sj0" + : "__gcj_personality_v0"); + lang_eh_runtime_type = prepare_eh_table_type; + init_jcf_parse (); /* Register nodes with the garbage collector. */ @@ -1828,8 +1828,6 @@ end_java_method () BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - emit_handlers (); - /* Generate rtl for function exit. */ expand_function_end (input_filename, lineno, 0); diff --git a/gcc/java/except.c b/gcc/java/except.c index f14d9437871..184f7e5a88b 100644 --- a/gcc/java/except.c +++ b/gcc/java/except.c @@ -34,7 +34,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "function.h" #include "except.h" #include "java-except.h" -#include "eh-common.h" #include "toplev.h" static void expand_start_java_handler PARAMS ((struct eh_range *)); @@ -250,14 +249,6 @@ method_init_exceptions () whole_range.first_child = NULL; whole_range.next_sibling = NULL; cache_range_start = 0xFFFFFF; - java_set_exception_lang_code (); -} - -void -java_set_exception_lang_code () -{ - set_exception_lang_code (EH_LANG_Java); - set_exception_version_code (1); } /* Add an exception range. If we already have an exception range @@ -339,7 +330,7 @@ prepare_eh_table_type (type) * (which yields a value with low-order bit 1). */ if (type == NULL_TREE) - exp = CATCH_ALL_TYPE; + exp = NULL_TREE; else if (is_compiled_class (type)) exp = build_class_ref (type); else @@ -350,7 +341,27 @@ prepare_eh_table_type (type) return exp; } -/* if there are any handlers for this range, isssue end of range, + +/* Build a reference to the jthrowable object being carried in the + exception header. */ + +tree +build_exception_object_ref (type) + tree type; +{ + tree obj; + + /* Java only passes object via pointer and doesn't require adjusting. + The java object is immediately before the generic exception header. */ + obj = build (EXC_PTR_EXPR, build_pointer_type (type)); + obj = build (MINUS_EXPR, TREE_TYPE (obj), obj, + TYPE_SIZE_UNIT (TREE_TYPE (obj))); + obj = build1 (INDIRECT_REF, type, obj); + + return obj; +} + +/* If there are any handlers for this range, isssue end of range, and then all handler blocks */ static void expand_end_java_handler (range) @@ -361,11 +372,9 @@ expand_end_java_handler (range) expand_start_all_catch (); for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler)) { - start_catch_handler (prepare_eh_table_type (TREE_PURPOSE (handler))); - /* Push the thrown object on the top of the stack */ + expand_start_catch (TREE_PURPOSE (handler)); expand_goto (TREE_VALUE (handler)); - expand_resume_after_catch (); - end_catch_handler (); + expand_end_catch (); } expand_end_all_catch (); #if defined(DEBUG_JAVA_BINDING_LEVELS) @@ -432,30 +441,3 @@ maybe_end_try (start_pc, end_pc) current_range = current_range->outer; } } - -/* Emit the handler labels and their code */ - -void -emit_handlers () -{ - if (catch_clauses) - { - rtx funcend = gen_label_rtx (); - emit_jump (funcend); - - emit_insns (catch_clauses); - catch_clauses = catch_clauses_last = NULL_RTX; - expand_leftover_cleanups (); - - emit_label (funcend); - } -} - -/* Resume executing at the statement immediately after the end of an - exception region. */ - -void -expand_resume_after_catch () -{ - expand_goto (top_label_entry (&caught_return_label_stack)); -} diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 42c43aad536..072be6dea94 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -2502,15 +2502,13 @@ java_lang_expand_expr (exp, target, tmode, modifier) for (current = TREE_OPERAND (exp, 1); current; current = TREE_CHAIN (current)) { - tree type; tree catch = TREE_OPERAND (current, 0); tree decl = BLOCK_EXPR_DECLS (catch); - type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE); - start_catch_handler (prepare_eh_table_type (type)); - expand_expr_stmt (TREE_OPERAND (current, 0)); + tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE); - expand_resume_after_catch (); - end_catch_handler (); + expand_start_catch (type); + expand_expr_stmt (TREE_OPERAND (current, 0)); + expand_end_catch (); } expand_end_all_catch (); return const0_rtx; @@ -2812,7 +2810,7 @@ process_jvm_instruction (PC, byte_ops, length) if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET) { tree type = pop_type (ptr_type_node); - push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node)); + push_value (build_exception_object_ref (type)); } switch (byte_ops[PC++]) diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 01a0722d39b..598caf4a46a 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -339,7 +339,6 @@ enum java_tree_index JTI_SOFT_GETJNIENVNEWFRAME_NODE, JTI_SOFT_JNIPOPSYSTEMFRAME_NODE, JTI_SOFT_FMOD_NODE, - JTI_SOFT_EXCEPTIONINFO_CALL_NODE, JTI_SOFT_IDIV_NODE, JTI_SOFT_IREM_NODE, JTI_SOFT_LDIV_NODE, @@ -581,8 +580,6 @@ extern tree java_global_trees[JTI_MAX]; java_global_trees[JTI_SOFT_JNIPOPSYSTEMFRAME_NODE] #define soft_fmod_node \ java_global_trees[JTI_SOFT_FMOD_NODE] -#define soft_exceptioninfo_call_node \ - java_global_trees[JTI_SOFT_EXCEPTIONINFO_CALL_NODE] #define soft_idiv_node \ java_global_trees[JTI_SOFT_IDIV_NODE] #define soft_irem_node \ @@ -1026,6 +1023,7 @@ extern tree build_instanceof PARAMS ((tree, tree)); extern tree create_label_decl PARAMS ((tree)); extern void push_labeled_block PARAMS ((tree)); extern tree prepare_eh_table_type PARAMS ((tree)); +extern tree build_exception_object_ref PARAMS ((tree)); extern void java_set_exception_lang_code PARAMS ((void)); extern tree generate_name PARAMS ((void)); extern void pop_labeled_block PARAMS ((void)); diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index b84c86ebde2..79ac6916679 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -2451,6 +2451,9 @@ generate_bytecode_insns (exp, target, state) } } break; + case EXC_PTR_EXPR: + NOTE_PUSH (1); /* Pushed by exception system. */ + break; case NEW_CLASS_EXPR: { tree class = TREE_TYPE (TREE_TYPE (exp)); @@ -2527,11 +2530,6 @@ generate_bytecode_insns (exp, target, state) NOTE_POP (1); break; } - else if (exp == soft_exceptioninfo_call_node) - { - NOTE_PUSH (1); /* Pushed by exception system. */ - break; - } for ( ; x != NULL_TREE; x = TREE_CHAIN (x)) { generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state); diff --git a/gcc/java/parse.h b/gcc/java/parse.h index 9ca55d4aa47..d17dbc0d1cb 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -661,14 +661,6 @@ typedef struct _jdeplist { build_new_invocation (wfl_string_buffer, \ (ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE)) -/* For exception handling, build diverse function calls */ -#define BUILD_ASSIGN_EXCEPTION_INFO(WHERE, TO) \ - { \ - (WHERE) = build (MODIFY_EXPR, void_type_node, (TO), \ - soft_exceptioninfo_call_node); \ - TREE_SIDE_EFFECTS (WHERE) = 1; \ - } - #define BUILD_THROW(WHERE, WHAT) \ { \ (WHERE) = \ diff --git a/gcc/java/parse.y b/gcc/java/parse.y index e09af7a8ebd..d377e8fe59d 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -1885,9 +1885,9 @@ catch_clause_parameter: declared initialized by the appropriate function call */ tree ccpb = enter_block (); - tree init = build_assignment (ASSIGN_TK, $2.location, - TREE_PURPOSE ($3), - soft_exceptioninfo_call_node); + tree init = build_assignment + (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), + build_exception_object_ref (ptr_type_node)); declare_local_variables (0, TREE_VALUE ($3), build_tree_list (TREE_PURPOSE ($3), init)); @@ -7124,9 +7124,6 @@ source_end_java_method () java_parser_context_save_global (); lineno = ctxp->last_ccb_indent1; - /* Set EH language codes */ - java_set_exception_lang_code (); - /* Turn function bodies with only a NOP expr null, so they don't get generated at all and we won't get warnings when using the -W -Wall flags. */ @@ -7148,8 +7145,6 @@ source_end_java_method () if (! flag_emit_class_files && ! flag_emit_xref) { lineno = DECL_SOURCE_LINE_LAST (fndecl); - /* Emit catch-finally clauses */ - emit_handlers (); expand_function_end (input_filename, lineno, 0); /* Run the optimizers and output assembler code for this function. */ @@ -8405,7 +8400,7 @@ build_dot_class_method (class) /* We initialize the variable with the exception handler. */ catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param, - soft_exceptioninfo_call_node); + build_exception_object_ref (ptr_type_node)); add_stmt_to_block (catch_block, NULL_TREE, catch); /* We add the statement throwing the new exception */ @@ -12609,7 +12604,7 @@ try_reference_assignconv (lhs_type, rhs) else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0)) new_rhs = rhs; /* This is a magic assignment that we process differently */ - else if (rhs == soft_exceptioninfo_call_node) + else if (TREE_CODE (rhs) == EXC_PTR_EXPR) new_rhs = rhs; } return new_rhs; diff --git a/gcc/jump.c b/gcc/jump.c index 958f8582400..2b111d4bd59 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -213,12 +213,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, cross_jump_death_matters = (cross_jump == 2); max_uid = init_label_info (f) + 1; - /* If we are performing cross jump optimizations, then initialize - tables mapping UIDs to EH regions to avoid incorrect movement - of insns from one EH region to another. */ - if (flag_exceptions && cross_jump) - init_insn_eh_region (f, max_uid); - if (! mark_labels_only) delete_barrier_successors (f); @@ -237,8 +231,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL) LABEL_NUSES (XEXP (insn, 0))++; - check_exception_handler_labels (); - /* Keep track of labels used for marking handlers for exception regions; they cannot usually be deleted. */ @@ -251,9 +243,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, if (mark_labels_only) goto end; - if (! minimal) - exception_optimize (); - last_insn = delete_unreferenced_labels (f); if (noop_moves) @@ -1444,13 +1433,6 @@ find_cross_jump (e1, e2, minimum, f1, f2) if (i2 == 0 || GET_CODE (i1) != GET_CODE (i2)) break; - /* Avoid moving insns across EH regions if either of the insns - can throw. */ - if (flag_exceptions - && (flag_non_call_exceptions || GET_CODE (i1) == CALL_INSN) - && !in_same_eh_region (i1, i2)) - break; - p1 = PATTERN (i1); p2 = PATTERN (i2); diff --git a/gcc/libgcc-std.ver b/gcc/libgcc-std.ver index 8efdd226c78..483d95d0c4e 100644 --- a/gcc/libgcc-std.ver +++ b/gcc/libgcc-std.ver @@ -114,28 +114,27 @@ GCC_3.0 { __gcc_bcmp # EH symbols - __default_terminate + _Unwind_DeleteException + _Unwind_ForcedUnwind + _Unwind_GetGR + _Unwind_GetIP + _Unwind_GetLanguageSpecificData + _Unwind_GetRegionStart + _Unwind_RaiseException + _Unwind_Resume + _Unwind_SetGR + _Unwind_SetIP __deregister_frame __deregister_frame_info - __eh_alloc - __eh_free - __eh_rtime_match - __frame_state_for - __get_dynamic_handler_chain - __get_eh_context - __get_eh_info - __get_eh_table_language - __get_eh_table_version __register_frame __register_frame_info __register_frame_info_table __register_frame_table - __rethrow - __sjpopnthrow - __sjthrow - __terminate - __terminate_set_func - __throw - __throw_type_match - __unwinding_cleanup + + # SjLj EH symbols + _Unwind_SjLj_Register + _Unwind_SjLj_Unregister + _Unwind_SjLj_RaiseException + _Unwind_SjLj_ForcedUnwind + _Unwind_SjLj_Resume } diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index 9e7aa99ae94..140f1f74fc3 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -3129,1221 +3129,3 @@ atexit (func_ptr func) #endif /* NEED_ATEXIT */ #endif /* L_exit */ - -#ifdef L_eh - -#include "gthr.h" - -/* Shared exception handling support routines. */ - -void -__default_terminate (void) -{ - abort (); -} - -static __terminate_func_ptr __terminate_func = - __default_terminate; - -void __attribute__((__noreturn__)) -__terminate (void) -{ - (*__terminate_func)(); -} - -__terminate_func_ptr -__terminate_set_func (__terminate_func_ptr newfunc) -{ - __terminate_func_ptr oldfunc = __terminate_func; - - __terminate_func = newfunc; - return (oldfunc); -} - -void * -__throw_type_match (void *catch_type, void *throw_type, void *obj) -{ -#if 0 - printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n", - catch_type, throw_type); -#endif - if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0) - return obj; - return 0; -} - -void -__empty (void) -{ -} - - -/* Include definitions of EH context and table layout */ - -#include "eh-common.h" -#ifndef inhibit_libc -#include -#endif - -/* Allocate and return a new EH context structure. */ - -#if __GTHREADS -static void * -new_eh_context (void) -{ - struct eh_full_context { - struct eh_context c; - void *top_elt[2]; - } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc); - - if (! ehfc) - __terminate (); - - memset (ehfc, 0, sizeof *ehfc); - - ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt; - - /* This should optimize out entirely. This should always be true, - but just in case it ever isn't, don't allow bogus code to be - generated. */ - - if ((void*)(&ehfc->c) != (void*)ehfc) - __terminate (); - - return &ehfc->c; -} - -static __gthread_key_t eh_context_key; - -/* Destructor for struct eh_context. */ -static void -eh_context_free (void *ptr) -{ - __gthread_key_dtor (eh_context_key, ptr); - if (ptr) - free (ptr); -} -#endif - -/* Pointer to function to return EH context. */ - -static struct eh_context *eh_context_initialize (void); -static struct eh_context *eh_context_static (void); -#if __GTHREADS -static struct eh_context *eh_context_specific (void); -#endif - -static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize; - -/* Routine to get EH context. - This one will simply call the function pointer. */ - -void * -__get_eh_context (void) -{ - return (void *) (*get_eh_context) (); -} - -/* Get and set the language specific info pointer. */ - -void ** -__get_eh_info (void) -{ - struct eh_context *eh = (*get_eh_context) (); - return &eh->info; -} - -#ifdef DWARF2_UNWIND_INFO -static int dwarf_reg_size_table_initialized = 0; -static char dwarf_reg_size_table[DWARF_FRAME_REGISTERS]; - -static void -init_reg_size_table (void) -{ - __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table); - dwarf_reg_size_table_initialized = 1; -} -#endif - -#if __GTHREADS -static void -eh_threads_initialize (void) -{ - /* Try to create the key. If it fails, revert to static method, - otherwise start using thread specific EH contexts. */ - if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0) - get_eh_context = &eh_context_specific; - else - get_eh_context = &eh_context_static; -} -#endif /* no __GTHREADS */ - -/* Initialize EH context. - This will be called only once, since we change GET_EH_CONTEXT - pointer to another routine. */ - -static struct eh_context * -eh_context_initialize (void) -{ -#if __GTHREADS - - static __gthread_once_t once = __GTHREAD_ONCE_INIT; - /* Make sure that get_eh_context does not point to us anymore. - Some systems have dummy thread routines in their libc that - return a success (Solaris 2.6 for example). */ - if (__gthread_once (&once, eh_threads_initialize) != 0 - || get_eh_context == &eh_context_initialize) - { - /* Use static version of EH context. */ - get_eh_context = &eh_context_static; - } -#ifdef DWARF2_UNWIND_INFO - { - static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT; - if (__gthread_once (&once_regsizes, init_reg_size_table) != 0 - || ! dwarf_reg_size_table_initialized) - init_reg_size_table (); - } -#endif - -#else /* no __GTHREADS */ - - /* Use static version of EH context. */ - get_eh_context = &eh_context_static; - -#ifdef DWARF2_UNWIND_INFO - init_reg_size_table (); -#endif - -#endif /* no __GTHREADS */ - - return (*get_eh_context) (); -} - -/* Return a static EH context. */ - -static struct eh_context * -eh_context_static (void) -{ - static struct eh_context eh; - static int initialized; - static void *top_elt[2]; - - if (! initialized) - { - initialized = 1; - memset (&eh, 0, sizeof eh); - eh.dynamic_handler_chain = top_elt; - } - return &eh; -} - -#if __GTHREADS -/* Return a thread specific EH context. */ - -static struct eh_context * -eh_context_specific (void) -{ - struct eh_context *eh; - eh = (struct eh_context *) __gthread_getspecific (eh_context_key); - if (! eh) - { - eh = new_eh_context (); - if (__gthread_setspecific (eh_context_key, (void *) eh) != 0) - __terminate (); - } - - return eh; -} -#endif /* __GTHREADS */ - -/* Support routines for alloc/free during exception handling */ - -/* __eh_alloc and __eh_free attempt allocation using malloc, but fall back to - the small arena in the eh_context. This is needed because throwing an - out-of-memory exception would fail otherwise. The emergency space is - allocated in blocks of size EH_ALLOC_ALIGN, the - minimum allocation being two blocks. A bitmask indicates which blocks - have been allocated. To indicate the size of an allocation, the bit for - the final block is not set. Hence each allocation is a run of 1s followed - by a zero. */ -void * -__eh_alloc (size_t size) -{ - void *p; - - if (!size) - abort(); - p = malloc (size); - if (p == 0) - { - struct eh_context *eh = __get_eh_context (); - unsigned blocks = (size + EH_ALLOC_ALIGN - 1) / EH_ALLOC_ALIGN; - unsigned real_mask = eh->alloc_mask | (eh->alloc_mask << 1); - unsigned our_mask; - unsigned ix; - - if (blocks > EH_ALLOC_SIZE / EH_ALLOC_ALIGN) - __terminate (); - blocks += blocks == 1; - our_mask = (1 << blocks) - 1; - - for (ix = EH_ALLOC_SIZE / EH_ALLOC_ALIGN - blocks; ix; ix--) - if (! ((real_mask >> ix) & our_mask)) - { - /* found some space */ - p = &eh->alloc_buffer[ix * EH_ALLOC_ALIGN]; - eh->alloc_mask |= (our_mask >> 1) << ix; - return p; - } - __terminate (); - } - return p; -} - -/* Free the memory for an cp_eh_info and associated exception, given - a pointer to the cp_eh_info. */ -void -__eh_free (void *p) -{ - struct eh_context *eh = __get_eh_context (); - - ptrdiff_t diff = (char *)p - &eh->alloc_buffer[0]; - if (diff >= 0 && diff < EH_ALLOC_SIZE) - { - unsigned mask = eh->alloc_mask; - unsigned bit = 1 << (diff / EH_ALLOC_ALIGN); - - do - { - mask ^= bit; - bit <<= 1; - } - while (mask & bit); - eh->alloc_mask = mask; - } - else - free (p); -} - -/* Support routines for setjmp/longjmp exception handling. */ - -/* Calls to __sjthrow are generated by the compiler when an exception - is raised when using the setjmp/longjmp exception handling codegen - method. */ - -#ifdef DONT_USE_BUILTIN_SETJMP -extern void longjmp (void *, int); -#endif - -/* Routine to get the head of the current thread's dynamic handler chain - use for exception handling. */ - -void *** -__get_dynamic_handler_chain (void) -{ - struct eh_context *eh = (*get_eh_context) (); - return &eh->dynamic_handler_chain; -} - -/* This is used to throw an exception when the setjmp/longjmp codegen - method is used for exception handling. - - We call __terminate if there are no handlers left. Otherwise we run the - cleanup actions off the dynamic cleanup stack, and pop the top of the - dynamic handler chain, and use longjmp to transfer back to the associated - handler. */ - -void -__sjthrow (void) -{ - struct eh_context *eh = (*get_eh_context) (); - void ***dhc = &eh->dynamic_handler_chain; - void *jmpbuf; - void (*func)(void *, int); - void *arg; - /* The cleanup chain is one word into the buffer. Get the cleanup chain. */ - void ***cleanup = (void***)&(*dhc)[1]; - - /* If there are any cleanups in the chain, run them now. */ - if (cleanup[0]) - { - double store[200]; - void **buf = (void**)store; - buf[1] = 0; - buf[0] = (*dhc); - - /* try { */ -#ifdef DONT_USE_BUILTIN_SETJMP - if (! setjmp (&buf[2])) -#else - if (! __builtin_setjmp (&buf[2])) -#endif - { - *dhc = buf; - while (cleanup[0]) - { - func = (void(*)(void*, int))cleanup[0][1]; - arg = (void*)cleanup[0][2]; - - /* Update this before running the cleanup. */ - cleanup[0] = (void **)cleanup[0][0]; - - (*func)(arg, 2); - } - *dhc = buf[0]; - } - /* catch (...) */ - else - { - __terminate (); - } - } - - /* We must call terminate if we try and rethrow an exception, when - there is no exception currently active and when there are no - handlers left. */ - if (! eh->info || (*dhc)[0] == 0) - __terminate (); - - /* Find the jmpbuf associated with the top element of the dynamic - handler chain. The jumpbuf starts two words into the buffer. */ - jmpbuf = &(*dhc)[2]; - - /* Then we pop the top element off the dynamic handler chain. */ - *dhc = (void**)(*dhc)[0]; - - /* And then we jump to the handler. */ - -#ifdef DONT_USE_BUILTIN_SETJMP - longjmp (jmpbuf, 1); -#else - __builtin_longjmp (jmpbuf, 1); -#endif -} - -/* Run cleanups on the dynamic cleanup stack for the current dynamic - handler, then pop the handler off the dynamic handler stack, and - then throw. This is used to skip the first handler, and transfer - control to the next handler in the dynamic handler stack. */ - -void -__sjpopnthrow (void) -{ - struct eh_context *eh = (*get_eh_context) (); - void ***dhc = &eh->dynamic_handler_chain; - void (*func)(void *, int); - void *arg; - /* The cleanup chain is one word into the buffer. Get the cleanup chain. */ - void ***cleanup = (void***)&(*dhc)[1]; - - /* If there are any cleanups in the chain, run them now. */ - if (cleanup[0]) - { - double store[200]; - void **buf = (void**)store; - buf[1] = 0; - buf[0] = (*dhc); - - /* try { */ -#ifdef DONT_USE_BUILTIN_SETJMP - if (! setjmp (&buf[2])) -#else - if (! __builtin_setjmp (&buf[2])) -#endif - { - *dhc = buf; - while (cleanup[0]) - { - func = (void(*)(void*, int))cleanup[0][1]; - arg = (void*)cleanup[0][2]; - - /* Update this before running the cleanup. */ - cleanup[0] = (void **)cleanup[0][0]; - - (*func)(arg, 2); - } - *dhc = buf[0]; - } - /* catch (...) */ - else - { - __terminate (); - } - } - - /* Then we pop the top element off the dynamic handler chain. */ - *dhc = (void**)(*dhc)[0]; - - __sjthrow (); -} - -/* Support code for all exception region-based exception handling. */ - -int -__eh_rtime_match (void *rtime) -{ - void *info; - __eh_matcher matcher; - void *ret; - - info = *(__get_eh_info ()); - matcher = ((__eh_info *)info)->match_function; - if (! matcher) - { -#ifndef inhibit_libc - fprintf (stderr, "Internal Compiler Bug: No runtime type matcher."); -#endif - return 0; - } - ret = (*matcher) (info, rtime, (void *)0); - return (ret != NULL); -} - -/* This value identifies the place from which an exception is being - thrown. */ - -#ifdef EH_TABLE_LOOKUP - -EH_TABLE_LOOKUP - -#else - -#ifdef DWARF2_UNWIND_INFO - -/* Return the table version of an exception descriptor */ - -short -__get_eh_table_version (exception_descriptor *table) -{ - return table->lang.version; -} - -/* Return the originating table language of an exception descriptor */ - -short -__get_eh_table_language (exception_descriptor *table) -{ - return table->lang.language; -} - -/* This routine takes a PC and a pointer to the exception region TABLE for - its translation unit, and returns the address of the exception handler - associated with the closest exception table handler entry associated - with that PC, or 0 if there are no table entries the PC fits in. - - In the advent of a tie, we have to give the last entry, as it represents - an inner block. */ - -static void * -old_find_exception_handler (void *pc, old_exception_table *table) -{ - if (table) - { - int pos; - int best = -1; - - /* We can't do a binary search because the table isn't guaranteed - to be sorted from function to function. */ - for (pos = 0; table[pos].start_region != (void *) -1; ++pos) - { - if (table[pos].start_region <= pc && table[pos].end_region > pc) - { - /* This can apply. Make sure it is at least as small as - the previous best. */ - if (best == -1 || (table[pos].end_region <= table[best].end_region - && table[pos].start_region >= table[best].start_region)) - best = pos; - } - /* But it is sorted by starting PC within a function. */ - else if (best >= 0 && table[pos].start_region > pc) - break; - } - if (best != -1) - return table[best].exception_handler; - } - - return (void *) 0; -} - -/* find_exception_handler finds the correct handler, if there is one, to - handle an exception. - returns a pointer to the handler which controlled should be transferred - to, or NULL if there is nothing left. - Parameters: - PC - pc where the exception originates. If this is a rethrow, - then this starts out as a pointer to the exception table - entry we wish to rethrow out of. - TABLE - exception table for the current module. - EH_INFO - eh info pointer for this exception. - RETHROW - 1 if this is a rethrow. (see incoming value of PC). - CLEANUP - returned flag indicating whether this is a cleanup handler. -*/ -static void * -find_exception_handler (void *pc, exception_descriptor *table, - __eh_info *eh_info, int rethrow, int *cleanup) -{ - - void *retval = NULL; - *cleanup = 1; - if (table) - { - int pos = 0; - /* The new model assumed the table is sorted inner-most out so the - first region we find which matches is the correct one */ - - exception_table *tab = &(table->table[0]); - - /* Subtract 1 from the PC to avoid hitting the next region */ - if (rethrow) - { - /* pc is actually the region table entry to rethrow out of */ - pos = ((exception_table *) pc) - tab; - pc = ((exception_table *) pc)->end_region - 1; - - /* The label is always on the LAST handler entry for a region, - so we know the next entry is a different region, even if the - addresses are the same. Make sure its not end of table tho. */ - if (tab[pos].start_region != (void *) -1) - pos++; - } - else - pc--; - - /* We can't do a binary search because the table is in inner-most - to outermost address ranges within functions */ - for ( ; tab[pos].start_region != (void *) -1; pos++) - { - if (tab[pos].start_region <= pc && tab[pos].end_region > pc) - { - if (tab[pos].match_info) - { - __eh_matcher matcher = eh_info->match_function; - /* match info but no matcher is NOT a match */ - if (matcher) - { - void *ret = (*matcher)((void *) eh_info, - tab[pos].match_info, table); - if (ret) - { - if (retval == NULL) - retval = tab[pos].exception_handler; - *cleanup = 0; - break; - } - } - } - else - { - if (retval == NULL) - retval = tab[pos].exception_handler; - } - } - } - } - return retval; -} -#endif /* DWARF2_UNWIND_INFO */ -#endif /* EH_TABLE_LOOKUP */ - -#ifdef DWARF2_UNWIND_INFO -/* Support code for exception handling using static unwind information. */ - -#include "frame.h" - -/* This type is used in get_reg and put_reg to deal with ABIs where a void* - is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to - avoid a warning about casting between int and pointer of different - sizes. */ - -typedef int ptr_type __attribute__ ((mode (pointer))); - -typedef struct -{ - word_type *reg[DWARF_FRAME_REGISTERS]; -} saved_regs_t; - -#ifdef INCOMING_REGNO -/* Is the saved value for register REG in frame UDATA stored in a register - window in the previous frame? */ - -/* ??? The Sparc INCOMING_REGNO references TARGET_FLAT. This allows us - to use the macro here. One wonders, though, that perhaps TARGET_FLAT - compiled functions won't work with the frame-unwind stuff here. - Perhaps the entireity of in_reg_window should be conditional on having - seen a DW_CFA_GNU_window_save? */ -#define target_flags 0 - -static int -in_reg_window (int reg, frame_state *udata) -{ - if (udata->saved[reg] == REG_SAVED_REG) - return INCOMING_REGNO (reg) == reg; - if (udata->saved[reg] != REG_SAVED_OFFSET) - return 0; - -#ifdef STACK_GROWS_DOWNWARD - return udata->reg_or_offset[reg] > 0; -#else - return udata->reg_or_offset[reg] < 0; -#endif -} -#else -static inline int -in_reg_window (int reg __attribute__ ((__unused__)), - frame_state *udata __attribute__ ((__unused__))) -{ - return 0; -} -#endif /* INCOMING_REGNO */ - -/* Get the address of register REG as saved in UDATA, where SUB_UDATA is a - frame called by UDATA or 0. */ - -static word_type * -get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata) -{ - while (udata->saved[reg] == REG_SAVED_REG) - { - reg = udata->reg_or_offset[reg]; - if (in_reg_window (reg, udata)) - { - udata = sub_udata; - sub_udata = NULL; - } - } - if (udata->saved[reg] == REG_SAVED_OFFSET) - return (word_type *)(udata->cfa + udata->reg_or_offset[reg]); - else - /* We don't have a saved copy of this register. */ - return NULL; -} - -/* Get the value of register REG as saved in UDATA, where SUB_UDATA is a - frame called by UDATA or 0. */ - -static inline void * -get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata) -{ - return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata); -} - -/* Overwrite the saved value for register REG in frame UDATA with VAL. */ - -static inline void -put_reg (unsigned reg, void *val, frame_state *udata) -{ - *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val; -} - -/* Copy the saved value for register REG from PTREG to frame - TARGET_UDATA. Unlike the previous two functions, this can handle - registers that are not one word large. */ - -static void -copy_reg (unsigned reg, word_type *preg, frame_state *target_udata) -{ - word_type *ptreg = get_reg_addr (reg, target_udata, NULL); - memcpy (ptreg, preg, dwarf_reg_size_table [reg]); -} - -/* Retrieve the return address for frame UDATA. */ - -static inline void * -get_return_addr (frame_state *udata, frame_state *sub_udata) -{ - return __builtin_extract_return_addr - (get_reg (udata->retaddr_column, udata, sub_udata)); -} - -/* Overwrite the return address for frame UDATA with VAL. */ - -static inline void -put_return_addr (void *val, frame_state *udata) -{ - val = __builtin_frob_return_addr (val); - put_reg (udata->retaddr_column, val, udata); -} - -/* Given the current frame UDATA and its return address PC, return the - information about the calling frame in CALLER_UDATA and update the - register array in SAVED_REGS. */ - -static void * -next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata, - saved_regs_t *saved_regs) -{ - int i; - word_type *p; - - /* Collect all of the registers for the current frame. */ - for (i = 0; i < DWARF_FRAME_REGISTERS; i++) - if (udata->saved[i]) - saved_regs->reg[i] = get_reg_addr (i, udata, caller_udata); - - caller_udata = __frame_state_for (pc, caller_udata); - if (! caller_udata) - return 0; - - /* Now go back to our caller's stack frame. If our caller's CFA was - saved in a register in this stack frame or a previous one, restore it; - otherwise, assume CFA register is SP and restore it to our CFA value - (which is defined to be the value of SP in the caller's frame). */ - - p = saved_regs->reg[caller_udata->cfa_reg]; - if (p) - caller_udata->cfa = (void *)(ptr_type)*p; - else - caller_udata->cfa = udata->cfa; - - if (caller_udata->indirect) - caller_udata->cfa = * (void **) ((unsigned char *)caller_udata->cfa - + caller_udata->base_offset); - caller_udata->cfa += caller_udata->cfa_offset; - - return caller_udata; -} - -/* Hook to call before __terminate if only cleanup handlers remain. */ -void -__unwinding_cleanup (void) -{ -} - -/* throw_helper performs some of the common grunt work for a throw. This - routine is called by throw and rethrows. This is pretty much split - out from the old __throw routine. An addition has been added which allows - for a dummy call to a routine __unwinding_cleanup() when there are nothing - but cleanups remaining. This allows a debugger to examine the state - at which the throw was executed, before any cleanups, rather than - at the terminate point after the stack has been unwound. - - EH is the current eh_context structure. - PC is the address of the call to __throw. - MY_UDATA is the unwind information for __throw. - OFFSET_P is where we return the SP adjustment offset. */ - -static void * -throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata, - long *offset_p) -{ - frame_state ustruct2, *udata = &ustruct2; - frame_state ustruct; - frame_state *sub_udata = &ustruct; - void *saved_pc = pc; - void *handler; - void *handler_p = 0; - void *pc_p = 0; - void *callee_cfa = 0; - frame_state saved_ustruct; - int new_eh_model; - int cleanup = 0; - int only_cleanup = 0; - int rethrow = 0; - int saved_state = 0; - long args_size; - saved_regs_t saved_regs, cleanup_regs; - __eh_info *eh_info = (__eh_info *)eh->info; - int i; - - memset (saved_regs.reg, 0, sizeof saved_regs.reg); - memset (sub_udata->saved, REG_UNSAVED, sizeof sub_udata->saved); - - /* Do we find a handler based on a re-throw PC? */ - if (eh->table_index != (void *) 0) - rethrow = 1; - - memcpy (udata, my_udata, sizeof (*udata)); - - handler = (void *) 0; - for (;;) - { - frame_state *p = udata; - - udata = next_stack_level (pc, udata, sub_udata, &saved_regs); - sub_udata = p; - - /* If we couldn't find the next frame, we lose. */ - if (! udata) - break; - - if (udata->eh_ptr == NULL) - new_eh_model = 0; - else - new_eh_model = (((exception_descriptor *)(udata->eh_ptr))-> - runtime_id_field == NEW_EH_RUNTIME); - - if (rethrow) - { - rethrow = 0; - handler = find_exception_handler (eh->table_index, udata->eh_ptr, - eh_info, 1, &cleanup); - eh->table_index = (void *)0; - } - else - if (new_eh_model) - handler = find_exception_handler (pc, udata->eh_ptr, eh_info, - 0, &cleanup); - else - handler = old_find_exception_handler (pc, udata->eh_ptr); - - /* If we found one, we can stop searching, if its not a cleanup. - for cleanups, we save the state, and keep looking. This allows - us to call a debug hook if there are nothing but cleanups left. */ - if (handler) - { - /* sub_udata now refers to the frame called by the handler frame. */ - - if (cleanup) - { - if (!saved_state) - { - saved_ustruct = *udata; - cleanup_regs = saved_regs; - handler_p = handler; - pc_p = pc; - saved_state = 1; - only_cleanup = 1; - /* Save the CFA of the frame called by the handler - frame. */ - callee_cfa = sub_udata->cfa; - } - } - else - { - only_cleanup = 0; - if (!saved_state) - callee_cfa = sub_udata->cfa; - break; - } - } - - /* Otherwise, we continue searching. We subtract 1 from PC to avoid - hitting the beginning of the next region. */ - pc = get_return_addr (udata, sub_udata) - 1; - } - - if (saved_state) - { - udata = &saved_ustruct; - saved_regs = cleanup_regs; - handler = handler_p; - pc = pc_p; - if (only_cleanup) - __unwinding_cleanup (); - } - - /* If we haven't found a handler by now, this is an unhandled - exception. */ - if (! handler) - __terminate(); - - eh->handler_label = handler; - - args_size = udata->args_size; - - /* We adjust SP by the difference between __throw's CFA and the CFA for - the frame called by the handler frame, because those CFAs correspond - to the SP values at the two call sites. We need to further adjust by - the args_size of the handler frame itself to get the handler frame's - SP from before the args were pushed for that call. */ -#ifdef STACK_GROWS_DOWNWARD - *offset_p = callee_cfa - my_udata->cfa + args_size; -#else - *offset_p = my_udata->cfa - callee_cfa - args_size; -#endif - - /* If we found a handler in the throw context there's no need to - unwind. */ - if (pc != saved_pc) - { - /* Copy saved register values into our register save slots. */ - for (i = 0; i < DWARF_FRAME_REGISTERS; i++) - if (i != udata->retaddr_column && saved_regs.reg[i]) - copy_reg (i, saved_regs.reg[i], my_udata); - } - - return handler; -} - - -/* We first search for an exception handler, and if we don't find - it, we call __terminate on the current stack frame so that we may - use the debugger to walk the stack and understand why no handler - was found. - - If we find one, then we unwind the frames down to the one that - has the handler and transfer control into the handler. */ - -/*extern void __throw(void) __attribute__ ((__noreturn__));*/ - -void -__throw (void) -{ - struct eh_context *eh = (*get_eh_context) (); - void *pc, *handler; - long offset; - - /* XXX maybe make my_ustruct static so we don't have to look it up for - each throw. */ - frame_state my_ustruct, *my_udata = &my_ustruct; - - /* This is required for C++ semantics. We must call terminate if we - try and rethrow an exception, when there is no exception currently - active. */ - if (! eh->info) - __terminate (); - - /* Start at our stack frame. */ -label: - my_udata = __frame_state_for (&&label, my_udata); - if (! my_udata) - __terminate (); - - /* We need to get the value from the CFA register. */ - my_udata->cfa = __builtin_dwarf_cfa (); - - /* Do any necessary initialization to access arbitrary stack frames. - On the SPARC, this means flushing the register windows. */ - __builtin_unwind_init (); - - /* Now reset pc to the right throw point. The return address points to - the instruction after the call to __throw; we subtract 1 so that pc - points into the call insn itself. Since we work with PC ranges (as - opposed to specific call sites), it isn't important for it to point to - the very beginning of the call insn, and making it do so would be - hard on targets with variable length call insns. */ - pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1; - - handler = throw_helper (eh, pc, my_udata, &offset); - - /* Now go! */ - - __builtin_eh_return ((void *)eh, offset, handler); - - /* Epilogue: restore the handler frame's register values and return - to the stub. */ -} - -/*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/ - -void -__rethrow (void *index) -{ - struct eh_context *eh = (*get_eh_context) (); - void *pc, *handler; - long offset; - - /* XXX maybe make my_ustruct static so we don't have to look it up for - each throw. */ - frame_state my_ustruct, *my_udata = &my_ustruct; - - /* This is required for C++ semantics. We must call terminate if we - try and rethrow an exception, when there is no exception currently - active. */ - if (! eh->info) - __terminate (); - - /* This is the table index we want to rethrow from. The value of - the END_REGION label is used for the PC of the throw, and the - search begins with the next table entry. */ - eh->table_index = index; - - /* Start at our stack frame. */ -label: - my_udata = __frame_state_for (&&label, my_udata); - if (! my_udata) - __terminate (); - - /* We need to get the value from the CFA register. */ - my_udata->cfa = __builtin_dwarf_cfa (); - - /* Do any necessary initialization to access arbitrary stack frames. - On the SPARC, this means flushing the register windows. */ - __builtin_unwind_init (); - - /* Now reset pc to the right throw point. The return address points to - the instruction after the call to __throw; we subtract 1 so that pc - points into the call insn itself. Since we work with PC ranges (as - opposed to specific call sites), it isn't important for it to point to - the very beginning of the call insn, and making it do so would be - hard on targets with variable length call insns. */ - pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1; - - handler = throw_helper (eh, pc, my_udata, &offset); - - /* Now go! */ - - __builtin_eh_return ((void *)eh, offset, handler); - - /* Epilogue: restore the handler frame's register values and return - to the stub. */ -} -#endif /* DWARF2_UNWIND_INFO */ - -#ifdef IA64_UNWIND_INFO -#include "frame.h" - -/* Return handler to which we want to transfer control, NULL if we don't - intend to handle this exception here. */ -void * -__ia64_personality_v1 (void *pc, old_exception_table *table) -{ - if (table) - { - int pos; - int best = -1; - - for (pos = 0; table[pos].start_region != (void *) -1; ++pos) - { - if (table[pos].start_region <= pc && table[pos].end_region > pc) - { - /* This can apply. Make sure it is at least as small as - the previous best. */ - if (best == -1 || (table[pos].end_region <= table[best].end_region - && table[pos].start_region >= table[best].start_region)) - best = pos; - } - /* It is sorted by starting PC within a function. */ - else if (best >= 0 && table[pos].start_region > pc) - break; - } - if (best != -1) - return table[best].exception_handler; - } - return (void *) 0; -} - -static void -ia64_throw_helper (ia64_frame_state *throw_frame, ia64_frame_state *caller, - void *throw_bsp, void *throw_sp) -{ - void *throw_pc = __builtin_return_address (0); - unwind_info_ptr *info; - void *pc, *handler = NULL; - void *pc_base; - int frame_count; - void *bsp; - - __builtin_ia64_flushrs (); /* Make the local register stacks available. */ - - /* Start at our stack frame, get our state. */ - __build_ia64_frame_state (throw_pc, throw_frame, throw_bsp, throw_sp, - &pc_base); - - /* Now we have to find the proper frame for pc, and see if there - is a handler for it. if not, we keep going back frames until - we do find one. Otherwise we call uncaught (). */ - - frame_count = 0; - memcpy (caller, throw_frame, sizeof (*caller)); - while (!handler) - { - void *(*personality) (void *, old_exception_table *); - void *eh_table; - - frame_count++; - /* We only care about the RP right now, so we dont need to keep - any other information about a call frame right now. */ - pc = __get_real_reg_value (&caller->rp) - 1; - bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs), - caller->my_bsp); - info = __build_ia64_frame_state (pc, caller, bsp, caller->my_psp, - &pc_base); - - /* If we couldn't find the next frame, we lose. */ - if (! info) - break; - - personality = __get_personality (info); - /* TODO Haven't figured out how to actually load the personality address - yet, so just always default to the one we expect for now. */ - if (personality != 0) - personality = __ia64_personality_v1; - eh_table = __get_except_table (info); - /* If there is no personality routine, we'll keep unwinding. */ - if (personality) - /* Pass a segment relative PC address to the personality routine, - because the unwind_info section uses segrel relocs. */ - handler = personality ((void *)(pc - pc_base), eh_table); - } - - if (!handler) - __terminate (); - - /* Handler is a segment relative address, so we must adjust it here. */ - handler += (long) pc_base; - - /* If we found a handler, we need to unwind the stack to that point. - We do this by copying saved values from previous frames into the - save slot for the throw_frame saved slots. when __throw returns, - it'll pickup the correct values. */ - - /* Start with where __throw saved things, and copy each saved register - of each previous frame until we get to the one before we're - throwing back to. */ - memcpy (caller, throw_frame, sizeof (*caller)); - for ( ; frame_count > 0; frame_count--) - { - pc = __get_real_reg_value (&caller->rp) - 1; - bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs), - caller->my_bsp); - __build_ia64_frame_state (pc, caller, bsp, caller->my_psp, &pc_base); - /* Any regs that were saved can be put in the throw frame now. */ - /* We don't want to copy any saved register from the - target destination, but we do want to load up it's frame. */ - if (frame_count > 1) - __copy_saved_reg_state (throw_frame, caller); - } - - /* Set return address of the throw frame to the handler. */ - __set_real_reg_value (&throw_frame->rp, handler); - - /* TODO, do we need to do anything to make the values we wrote 'stick'? */ - /* DO we need to go through the whole loadrs seqeunce? */ -} - - -void -__throw () -{ - register void *stack_pointer __asm__("r12"); - struct eh_context *eh = (*get_eh_context) (); - ia64_frame_state my_frame; - ia64_frame_state originator; /* For the context handler is in. */ - void *bsp, *tmp_bsp; - long offset; - - /* This is required for C++ semantics. We must call terminate if we - try and rethrow an exception, when there is no exception currently - active. */ - if (! eh->info) - __terminate (); - - __builtin_unwind_init (); - - /* We have to call another routine to actually process the frame - information, which will force all of __throw's local registers into - backing store. */ - - /* Get the value of ar.bsp while we're here. */ - - bsp = __builtin_ia64_bsp (); - ia64_throw_helper (&my_frame, &originator, bsp, stack_pointer); - - /* Now we have to fudge the bsp by the amount in our (__throw) - frame marker, since the return is going to adjust it by that much. */ - - tmp_bsp = __calc_caller_bsp ((long)__get_real_reg_value (&my_frame.pfs), - my_frame.my_bsp); - offset = (char *)my_frame.my_bsp - (char *)tmp_bsp; - tmp_bsp = (char *)originator.my_bsp + offset; - - __builtin_eh_return (tmp_bsp, offset, originator.my_sp); - - /* The return address was already set by throw_helper. */ -} - -#endif /* IA64_UNWIND_INFO */ - -#endif /* L_eh */ diff --git a/gcc/md.texi b/gcc/md.texi index 411f67fc754..047f25669a8 100644 --- a/gcc/md.texi +++ b/gcc/md.texi @@ -2848,26 +2848,24 @@ You will not normally need to define this pattern unless you also define @code{builtin_setjmp_setup}. The single argument is a pointer to the @code{jmp_buf}. -@cindex @code{eh_epilogue} instruction pattern -@item @samp{eh_epilogue} +@cindex @code{eh_return} instruction pattern +@item @samp{eh_return} This pattern, if defined, affects the way @code{__builtin_eh_return}, -and thence @code{__throw} are built. It is intended to allow communication -between the exception handling machinery and the normal epilogue code -for the target. - -The pattern takes three arguments. The first is the exception context -pointer. This will have already been copied to the function return -register appropriate for a pointer; normally this can be ignored. The -second argument is an offset to be added to the stack pointer. It will -have been copied to some arbitrary call-clobbered hard reg so that it -will survive until after reload to when the normal epilogue is generated. -The final argument is the address of the exception handler to which +and thence the call frame exception handling library routines, are +built. It is intended to handle non-trivial actions needed along +the abnormal return path. + +The pattern takes two arguments. The first is an offset to be applied +to the stack pointer. It will have been copied to some appropriate +location (typically @code{EH_RETURN_STACKADJ_RTX}) which will survive +until after reload to when the normal epilogue is generated. +The second argument is the address of the exception handler to which the function should return. This will normally need to copied by the -pattern to some special register. +pattern to some special register or memory location. -This pattern must be defined if @code{RETURN_ADDR_RTX} does not yield -something that can be reliably and permanently modified, i.e. a fixed -hard register or a stack memory reference. +This pattern only needs to be defined if call frame exception handling +is to be used, and simple moves to @code{EH_RETURN_STACKADJ_RTX} and +@code{EH_RETURN_HANDLER_RTX} are not sufficient. @cindex @code{prologue} instruction pattern @item @samp{prologue} diff --git a/gcc/mklibgcc.in b/gcc/mklibgcc.in index 6341b302b83..70fc55aa53c 100644 --- a/gcc/mklibgcc.in +++ b/gcc/mklibgcc.in @@ -14,8 +14,9 @@ # LIB1ASMFUNCS # LIB1FUNCS_EXTRA # LIB2FUNCS -# LIB2FUNCS_EH # LIB2ADD +# LIB2ADDEH +# LIB2ADDEHDEP # FPBIT # FPBIT_FUNCS # DPBIT @@ -79,7 +80,7 @@ make_compile='$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ libgcc1_c_dep='stmp-dirs $(srcdir)/libgcc1.c $(CONFIG_H)' # Dependancies for libgcc2.c -libgcc2_c_dep='stmp-dirs $(srcdir)/libgcc2.c $(CONFIG_H) $(MACHMODE_H) longlong.h frame.h gbl-ctors.h config.status stmp-int-hdrs tsystem.h' +libgcc2_c_dep='stmp-dirs $(srcdir)/libgcc2.c $(CONFIG_H) $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs tsystem.h'" $LIB2ADDEHDEP" # Dependancies for fp-bit.c fpbit_c_dep='stmp-dirs config.status tsystem.h' @@ -180,19 +181,6 @@ for name in $LIB2FUNCS; do libgcc2_objs="$libgcc2_objs ${name}${objext}" done -for name in $LIB2FUNCS_EH; do - for ml in $MULTILIBS; do - dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` - flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; - out="libgcc/${dir}/${name}${objext}" - - echo $out: $libgcc2_c_dep - echo " $gcc_compile" '$(MAYBE_USE_COLLECT2)' -fexceptions \ - $flags -DL$name -c '$(srcdir)/libgcc2.c' -o $out - done - libgcc2_objs="$libgcc2_objs ${name}${objext}" -done - if [ "$FPBIT" ]; then for name in $FPBIT_FUNCS; do for ml in $MULTILIBS; do @@ -241,6 +229,24 @@ for file in $LIB2ADD; do libgcc2_objs="$libgcc2_objs ${oname}${objext}" done +for file in $LIB2ADDEH; do + name=`echo $file | sed -e 's/[.][cSo]$//' -e 's/[.]asm$//' -e 's/[.]txt$//'` + oname=`echo $name | sed -e 's,.*/,,'` + + for ml in $MULTILIBS; do + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; + out="libgcc/${dir}/${oname}${objext}" + if [ ${name}.asm = ${file} ]; then + flags="$flags -xassembler-with-cpp" + fi + + echo $out: stmp-dirs $file + echo " $gcc_compile" $flags -fexceptions -c $file -o $out + done + libgcc2_objs="$libgcc2_objs ${oname}${objext}" +done + # SHLIB_MKMAP # SHLIB_MAPFILES for ml in $MULTILIBS; do diff --git a/gcc/optabs.c b/gcc/optabs.c index 0322510300d..0be8d6a6bce 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */ #include "tm_p.h" #include "flags.h" #include "function.h" +#include "except.h" #include "expr.h" #include "recog.h" #include "reload.h" @@ -4758,12 +4759,9 @@ init_optabs () memset_libfunc = init_one_libfunc ("memset"); bzero_libfunc = init_one_libfunc ("bzero"); - throw_libfunc = init_one_libfunc ("__throw"); - rethrow_libfunc = init_one_libfunc ("__rethrow"); - sjthrow_libfunc = init_one_libfunc ("__sjthrow"); - sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow"); - terminate_libfunc = init_one_libfunc ("__terminate"); - eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match"); + unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS + ? "_Unwind_SjLj_Resume" + : "_Unwind_Resume"); #ifndef DONT_USE_BUILTIN_SETJMP setjmp_libfunc = init_one_libfunc ("__builtin_setjmp"); longjmp_libfunc = init_one_libfunc ("__builtin_longjmp"); @@ -4771,6 +4769,9 @@ init_optabs () setjmp_libfunc = init_one_libfunc ("setjmp"); longjmp_libfunc = init_one_libfunc ("longjmp"); #endif + unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register"); + unwind_sjlj_unregister_libfunc + = init_one_libfunc ("_Unwind_SjLj_Unregister"); eqhf2_libfunc = init_one_libfunc ("__eqhf2"); nehf2_libfunc = init_one_libfunc ("__nehf2"); diff --git a/gcc/rtl.def b/gcc/rtl.def index 6f0aec86b5a..906255d2dcd 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -547,6 +547,11 @@ DEF_RTL_EXPR(RETURN, "return", "", 'x') For an unconditional trap, make the condition (const_int 1). */ DEF_RTL_EXPR(TRAP_IF, "trap_if", "ee", 'x') +/* Placeholder for _Unwind_Resume before we know if a function call + or a branch is needed. Operand 1 is the exception region from + which control is flowing. */ +DEF_RTL_EXPR(RESX, "resx", "i", 'x') + /* ---------------------------------------------------------------------- Primitive values for use in expressions. ---------------------------------------------------------------------- */ diff --git a/gcc/rtl.h b/gcc/rtl.h index a15fda29e55..dbadd70f958 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -924,10 +924,6 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS]; /* Flag in a SYMBOL_REF for machine-specific purposes. */ #define SYMBOL_REF_FLAG(RTX) ((RTX)->volatil) -/* 1 in a SYMBOL_REF if it represents a symbol which might have to change - if its inlined or unrolled. */ -#define SYMBOL_REF_NEED_ADJUST(RTX) ((RTX)->in_struct) - /* 1 means a SYMBOL_REF has been the library function in emit_library_call. */ #define SYMBOL_REF_USED(RTX) ((RTX)->used) diff --git a/gcc/stmt.c b/gcc/stmt.c index 743f8173429..12f1562cbf6 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -4072,12 +4072,11 @@ expand_decl_cleanup (decl, cleanup) start_sequence (); } - /* If this was optimized so that there is no exception region for the - cleanup, then mark the TREE_LIST node, so that we can later tell - if we need to call expand_eh_region_end. */ - if (! using_eh_for_cleanups_p - || expand_eh_region_start_tree (decl, cleanup)) + if (! using_eh_for_cleanups_p) TREE_ADDRESSABLE (t) = 1; + else + expand_eh_region_start (); + /* If that started a new EH region, we're in a new block. */ thisblock = block_stack; @@ -4106,82 +4105,6 @@ expand_decl_cleanup (decl, cleanup) } return 1; } - -/* Arrange for the top element of the dynamic cleanup chain to be - popped if we exit the current binding contour. DECL is the - associated declaration, if any, otherwise NULL_TREE. If the - current contour is left via an exception, then __sjthrow will pop - the top element off the dynamic cleanup chain. The code that - avoids doing the action we push into the cleanup chain in the - exceptional case is contained in expand_cleanups. - - This routine is only used by expand_eh_region_start, and that is - the only way in which an exception region should be started. This - routine is only used when using the setjmp/longjmp codegen method - for exception handling. */ - -int -expand_dcc_cleanup (decl) - tree decl; -{ - struct nesting *thisblock; - tree cleanup; - - /* Error if we are not in any block. */ - if (cfun == 0 || block_stack == 0) - return 0; - thisblock = block_stack; - - /* Record the cleanup for the dynamic handler chain. */ - - cleanup = make_node (POPDCC_EXPR); - - /* Add the cleanup in a manner similar to expand_decl_cleanup. */ - thisblock->data.block.cleanups - = tree_cons (decl, cleanup, thisblock->data.block.cleanups); - - /* If this block has a cleanup, it belongs in stack_block_stack. */ - stack_block_stack = thisblock; - return 1; -} - -/* Arrange for the top element of the dynamic handler chain to be - popped if we exit the current binding contour. DECL is the - associated declaration, if any, otherwise NULL_TREE. If the current - contour is left via an exception, then __sjthrow will pop the top - element off the dynamic handler chain. The code that avoids doing - the action we push into the handler chain in the exceptional case - is contained in expand_cleanups. - - This routine is only used by expand_eh_region_start, and that is - the only way in which an exception region should be started. This - routine is only used when using the setjmp/longjmp codegen method - for exception handling. */ - -int -expand_dhc_cleanup (decl) - tree decl; -{ - struct nesting *thisblock; - tree cleanup; - - /* Error if we are not in any block. */ - if (cfun == 0 || block_stack == 0) - return 0; - thisblock = block_stack; - - /* Record the cleanup for the dynamic handler chain. */ - - cleanup = make_node (POPDHC_EXPR); - - /* Add the cleanup in a manner similar to expand_decl_cleanup. */ - thisblock->data.block.cleanups - = tree_cons (decl, cleanup, thisblock->data.block.cleanups); - - /* If this block has a cleanup, it belongs in stack_block_stack. */ - stack_block_stack = thisblock; - return 1; -} /* DECL is an anonymous union. CLEANUP is a cleanup for DECL. DECL_ELTS is the list of elements that belong to DECL's type. @@ -4286,20 +4209,8 @@ expand_cleanups (list, dont_do, in_fixup, reachable) expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup, reachable); else { - if (! in_fixup) - { - tree cleanup = TREE_VALUE (tail); - - /* See expand_d{h,c}c_cleanup for why we avoid this. */ - if (TREE_CODE (cleanup) != POPDHC_EXPR - && TREE_CODE (cleanup) != POPDCC_EXPR - /* See expand_eh_region_start_tree for this case. */ - && ! TREE_ADDRESSABLE (tail)) - { - cleanup = protect_with_terminate (cleanup); - expand_eh_region_end (cleanup); - } - } + if (! in_fixup && using_eh_for_cleanups_p) + expand_eh_region_end_cleanup (TREE_VALUE (tail)); if (reachable) { @@ -4312,19 +4223,18 @@ expand_cleanups (list, dont_do, in_fixup, reachable) times, the control paths are non-overlapping so the cleanups will not be executed twice. */ - /* We may need to protect fixups with rethrow regions. */ - int protect = (in_fixup && ! TREE_ADDRESSABLE (tail)); + /* We may need to protect from outer cleanups. */ + if (in_fixup && using_eh_for_cleanups_p) + { + expand_eh_region_start (); + + expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); - if (protect) - expand_fixup_region_start (); + expand_eh_region_end_fixup (TREE_VALUE (tail)); + } + else + expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); - /* The cleanup might contain try-blocks, so we have to - preserve our current queue. */ - push_ehqueue (); - expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); - pop_ehqueue (); - if (protect) - expand_fixup_region_end (TREE_VALUE (tail)); free_temp_slots (); } } diff --git a/gcc/tm.texi b/gcc/tm.texi index 9f20053e07d..e3dd5309b20 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -2505,6 +2505,54 @@ You only need to define this macro if the default is incorrect, and you want to support call frame debugging information like that provided by DWARF 2. +@findex EH_RETURN_DATA_REGNO +@item EH_RETURN_DATA_REGNO (@var{N}) +A C expression whose value is the @var{N}th register number used for +data by exception handlers, or @code{INVALID_REGNUM} if fewer than +@var{N} registers are usable. + +The exception handling library routines communicate with the exception +handlers via a set of agreed upon registers. Ideally these registers +should be call-clobbered; it is possible to use call-saved registers, +but may negatively impact code size. The target must support at least +2 data registers, but should define 4 if there are enough free registers. + +You must define this macro if you want to support call frame exception +handling like that provided by DWARF 2. + +@findex EH_RETURN_STACKADJ_RTX +@item EH_RETURN_STACKADJ_RTX +A C expression whose value is RTL representing a location in which +to store a stack adjustment to be applied before function return. +This is used to unwind the stack to an exception handler's call frame. +It will be assigned zero on code paths that return normally. + +Typically this is a call-clobbered hard register that is otherwise +untouched by the epilogue, but could also be a stack slot. + +You must define this macro if you want to support call frame exception +handling like that provided by DWARF 2. + +@findex EH_RETURN_HANDLER_RTX +@item EH_RETURN_HANDLER_RTX +A C expression whose value is RTL representing a location in which +to store the address of an exception handler to which we should +return. It will not be assigned on code paths that return normally. + +Typically this is the location in the call frame at which the normal +return address is stored. For targets that return by popping an +address off the stack, this might be a memory address just below +the @emph{target} call frame rather than inside the current call +frame. @code{EH_RETURN_STACKADJ_RTX} will have already been assigned, +so it may be used to calculate the location of the target call frame. + +Some targets have more complex requirements than storing to an +address calculable during initial code generation. In that case +the @code{eh_return} instruction pattern should be used instead. + +If you want to support call frame exception handling, you must +define either this macro or the @code{eh_return} instruction pattern. + @findex SMALL_STACK @item SMALL_STACK Define this macro if the stack size for the target is very small. This diff --git a/gcc/toplev.c b/gcc/toplev.c index 6016ca6230b..b029c70642b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -252,6 +252,7 @@ enum dump_file_index { DFI_rtl, DFI_sibling, + DFI_eh, DFI_jump, DFI_cse, DFI_addressof, @@ -289,7 +290,7 @@ enum dump_file_index Remaining -d letters: - " h o q u " + " o q u " " H K OPQ TUVW YZ" */ @@ -297,6 +298,7 @@ struct dump_file_info dump_file[DFI_MAX] = { { "rtl", 'r', 0, 0, 0 }, { "sibling", 'i', 0, 0, 0 }, + { "eh", 'h', 0, 0, 0 }, { "jump", 'j', 0, 0, 0 }, { "cse", 's', 0, 0, 0 }, { "addressof", 'F', 0, 0, 0 }, @@ -2162,9 +2164,9 @@ compile_file (name) init_regs (); init_alias_once (); init_decl_processing (); + init_eh (); init_optabs (); init_stmt (); - init_eh (); init_loop (); init_reload (); init_function_once (); @@ -2402,14 +2404,6 @@ compile_file (name) loop above. */ output_func_start_profiler (); - /* Now that all possible functions have been output, we can dump - the exception table. */ - -#ifndef IA64_UNWIND_INFO - output_exception_table (); -#endif - free_exception_table (); - check_global_declarations (vec, len); /* Clean up. */ @@ -2805,6 +2799,11 @@ rest_of_compilation (decl) close_dump_file (DFI_rtl, print_rtl, insns); } + /* Convert from NOTE_INSN_EH_REGION style notes, and do other + sorts of eh initialization. Delay this until after the + initial rtl dump so that we can see the original nesting. */ + convert_from_eh_region_ranges (); + /* If function is inline, and we don't yet know whether to compile it by itself, defer decision till end of compilation. finish_compilation will call rest_of_compilation again @@ -2884,9 +2883,6 @@ rest_of_compilation (decl) if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) goto exit_rest_of_compilation; - /* Emit code to get eh context, if needed. */ - emit_eh_context (); - /* We may have potential sibling or tail recursion sites. Select one (of possibly multiple) methods of performing the call. */ if (flag_optimize_sibling_calls) @@ -2900,6 +2896,19 @@ rest_of_compilation (decl) timevar_pop (TV_JUMP); } + /* Complete generation of exception handling code. */ + find_exception_handler_labels (); + if (doing_eh (0)) + { + timevar_push (TV_JUMP); + open_dump_file (DFI_eh, decl); + + finish_eh_generation (); + + close_dump_file (DFI_eh, print_rtl, get_insns ()); + timevar_pop (TV_JUMP); + } + #ifdef FINALIZE_PIC /* If we are doing position-independent code generation, now is the time to output special prologues and epilogues. @@ -2923,9 +2932,6 @@ rest_of_compilation (decl) /* Instantiate all virtual registers. */ instantiate_virtual_regs (current_function_decl, insns); - /* Find all the EH handlers. */ - find_exception_handler_labels (); - open_dump_file (DFI_jump, decl); /* Always do one jump optimization pass to ensure that JUMP_LABEL fields @@ -3679,6 +3685,12 @@ rest_of_compilation (decl) } #endif +#ifndef STACK_REGS + /* ??? Do this before shorten branches so that we aren't creating + insns too late and fail sanity checks in final. */ + convert_to_eh_region_ranges (); +#endif + /* Shorten branches. Note this must run before reg-stack because of death note (ab)use @@ -3697,6 +3709,8 @@ rest_of_compilation (decl) timevar_pop (TV_REG_STACK); ggc_collect (); + + convert_to_eh_region_ranges (); #endif current_function_nothrow = nothrow_function_p (); @@ -3728,6 +3742,9 @@ rest_of_compilation (decl) final (insns, asm_out_file, optimize, 0); final_end_function (insns, asm_out_file, optimize); assemble_end_function (decl, fnname); + + output_function_exception_table (); + if (! quiet_flag) fflush (asm_out_file); diff --git a/gcc/tree.def b/gcc/tree.def index 399e05706a8..760600bcd2f 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -770,17 +770,6 @@ DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 'e', 2) Operand 1 is the rtx for a variable in which to store the address of where the subroutine should return to. */ DEFTREECODE (GOTO_SUBROUTINE_EXPR, "goto_subroutine", 'e', 2) - -/* Pop the top element off the dynamic handler chain. Used in - conjunction with setjmp/longjmp based exception handling, see - except.c for more details. This is meant to be used only by the - exception handling backend, expand_dhc_cleanup specifically. */ -DEFTREECODE (POPDHC_EXPR, "popdhc_expr", 's', 0) - -/* Pop the top element off the dynamic cleanup chain. Used in - conjunction with the exception handling. This is meant to be used - only by the exception handling backend. */ -DEFTREECODE (POPDCC_EXPR, "popdcc_expr", 's', 0) /* These types of expressions have no useful value, and always have side effects. */ @@ -834,6 +823,10 @@ DEFTREECODE (EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 3) Operand 1 contains the case values. The way they're organized is front-end implementation defined. */ DEFTREECODE (SWITCH_EXPR, "switch_expr", 'e', 2) + +/* The exception object from the runtime. */ +DEFTREECODE (EXC_PTR_EXPR, "exc_ptr_expr", 'e', 0) + /* Local variables: mode:c diff --git a/gcc/frame.c b/gcc/unwind-dw2-fde.c similarity index 66% rename from gcc/frame.c rename to gcc/unwind-dw2-fde.c index 399df577ff0..6f450c59bce 100644 --- a/gcc/frame.c +++ b/gcc/unwind-dw2-fde.c @@ -1,6 +1,5 @@ /* Subroutines needed for unwinding stack frames for exception handling. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by Jason Merrill . This file is part of GNU CC. @@ -29,6 +28,129 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "tconfig.h" +#include "tsystem.h" +#include "unwind-dw2-fde.h" +#include "gthr.h" + +static struct object *objects; + +#ifdef __GTHREAD_MUTEX_INIT +static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; +#else +static __gthread_mutex_t object_mutex; +#endif + +#ifdef __GTHREAD_MUTEX_INIT_FUNCTION +static void +init_object_mutex (void) +{ + __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex); +} + +static void +init_object_mutex_once (void) +{ + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + __gthread_once (&once, init_object_mutex); +} +#else +#define init_object_mutex_once() +#endif + +/* Called from crtbegin.o to register the unwind info for an object. */ + +void +__register_frame_info (void *begin, struct object *ob) +{ + ob->pc_begin = ob->pc_end = 0; + ob->fde_begin = begin; + ob->fde_array = 0; + ob->count = 0; + + init_object_mutex_once (); + __gthread_mutex_lock (&object_mutex); + + ob->next = objects; + objects = ob; + + __gthread_mutex_unlock (&object_mutex); +} + +void +__register_frame (void *begin) +{ + struct object *ob = (struct object *) malloc (sizeof (struct object)); + __register_frame_info (begin, ob); +} + +/* Similar, but BEGIN is actually a pointer to a table of unwind entries + for different translation units. Called from the file generated by + collect2. */ + +void +__register_frame_info_table (void *begin, struct object *ob) +{ + ob->pc_begin = ob->pc_end = 0; + ob->fde_begin = begin; + ob->fde_array = begin; + ob->count = 0; + + init_object_mutex_once (); + __gthread_mutex_lock (&object_mutex); + + ob->next = objects; + objects = ob; + + __gthread_mutex_unlock (&object_mutex); +} + +void +__register_frame_table (void *begin) +{ + struct object *ob = (struct object *) malloc (sizeof (struct object)); + __register_frame_info_table (begin, ob); +} + +/* Called from crtbegin.o to deregister the unwind info for an object. */ + +void * +__deregister_frame_info (void *begin) +{ + struct object **p; + + init_object_mutex_once (); + __gthread_mutex_lock (&object_mutex); + + p = &objects; + while (*p) + { + if ((*p)->fde_begin == begin) + { + struct object *ob = *p; + *p = (*p)->next; + + /* If we've run init_frame for this object, free the FDE array. */ + if (ob->fde_array && ob->fde_array != begin) + free (ob->fde_array); + + __gthread_mutex_unlock (&object_mutex); + return (void *) ob; + } + p = &((*p)->next); + } + + __gthread_mutex_unlock (&object_mutex); + abort (); +} + +void +__deregister_frame (void *begin) +{ + free (__deregister_frame_info (begin)); +} + + /* Sorting an array of FDEs by address. (Ideally we would have the linker sort the FDEs so we don't have to do it at run time. But the linkers are not yet prepared for this.) */ @@ -56,6 +178,12 @@ typedef struct fde_accumulator fde_vector erratic; } fde_accumulator; +static inline saddr +fde_compare (fde *x, fde *y) +{ + return (saddr)x->pc_begin - (saddr)y->pc_begin; +} + static inline int start_fde_sort (fde_accumulator *accu, size_t count) { @@ -241,97 +369,174 @@ end_fde_sort (fde_accumulator *accu, size_t count) return accu->linear.array; } -/* Called from crtbegin.o to register the unwind info for an object. */ + +static size_t +count_fdes (fde *this_fde) +{ + size_t count; -void -__register_frame_info (void *begin, struct object *ob) + for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde)) + /* Skip CIEs and omitted link-once FDE entries. */ + if (this_fde->CIE_delta != 0 && this_fde->pc_begin != 0) + ++count; + + return count; +} + +static void +add_fdes (fde *this_fde, fde_accumulator *accu, void **beg_ptr, void **end_ptr) { - ob->fde_begin = begin; + void *pc_begin = *beg_ptr; + void *pc_end = *end_ptr; - ob->pc_begin = ob->pc_end = 0; - ob->fde_array = 0; - ob->count = 0; + for (; this_fde->length != 0; this_fde = next_fde (this_fde)) + { + /* Skip CIEs and linked once FDE entries. */ + if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) + continue; - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); + fde_insert (accu, this_fde); - ob->next = objects; - objects = ob; + if (this_fde->pc_begin < pc_begin) + pc_begin = this_fde->pc_begin; + if (this_fde->pc_begin + this_fde->pc_range > pc_end) + pc_end = this_fde->pc_begin + this_fde->pc_range; + } - __gthread_mutex_unlock (&object_mutex); + *beg_ptr = pc_begin; + *end_ptr = pc_end; } -void -__register_frame (void *begin) +static fde * +search_fdes (fde *this_fde, void *pc) { - struct object *ob = (struct object *) malloc (sizeof (struct object)); - __register_frame_info (begin, ob); + for (; this_fde->length != 0; this_fde = next_fde (this_fde)) + { + /* Skip CIEs and linked once FDE entries. */ + if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) + continue; + + if ((uaddr)((char *)pc - (char *)this_fde->pc_begin) < this_fde->pc_range) + return this_fde; + } + return NULL; } -/* Similar, but BEGIN is actually a pointer to a table of unwind entries - for different translation units. Called from the file generated by - collect2. */ +/* Set up a sorted array of pointers to FDEs for a loaded object. We + count up the entries before allocating the array because it's likely to + be faster. We can be called multiple times, should we have failed to + allocate a sorted fde array on a previous occasion. */ -void -__register_frame_info_table (void *begin, struct object *ob) +static void +frame_init (struct object* ob) { - ob->fde_begin = begin; - ob->fde_array = begin; - - ob->pc_begin = ob->pc_end = 0; - ob->count = 0; + size_t count; + fde_accumulator accu; + void *pc_begin, *pc_end; + fde **array; - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); + if (ob->pc_begin) + count = ob->count; + else if (ob->fde_array) + { + fde **p = ob->fde_array; + for (count = 0; *p; ++p) + count += count_fdes (*p); + } + else + count = count_fdes (ob->fde_begin); + ob->count = count; - ob->next = objects; - objects = ob; + if (!start_fde_sort (&accu, count) && ob->pc_begin) + return; - __gthread_mutex_unlock (&object_mutex); -} + pc_begin = (void*)(uaddr)-1; + pc_end = 0; -void -__register_frame_table (void *begin) -{ - struct object *ob = (struct object *) malloc (sizeof (struct object)); - __register_frame_info_table (begin, ob); + if (ob->fde_array) + { + fde **p = ob->fde_array; + for (; *p; ++p) + add_fdes (*p, &accu, &pc_begin, &pc_end); + } + else + add_fdes (ob->fde_begin, &accu, &pc_begin, &pc_end); + array = end_fde_sort (&accu, count); + if (array) + ob->fde_array = array; + ob->pc_begin = pc_begin; + ob->pc_end = pc_end; } -/* Called from crtbegin.o to deregister the unwind info for an object. */ - -void * -__deregister_frame_info (void *begin) +fde * +_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) { - struct object **p; + struct object *ob; + size_t lo, hi; init_object_mutex_once (); __gthread_mutex_lock (&object_mutex); - p = &objects; - while (*p) + /* Linear search through the objects, to find the one containing the pc. */ + for (ob = objects; ob; ob = ob->next) { - if ((*p)->fde_begin == begin) - { - struct object *ob = *p; - *p = (*p)->next; + if (ob->pc_begin == 0) + frame_init (ob); + if (pc >= ob->pc_begin && pc < ob->pc_end) + break; + } - /* If we've run init_frame for this object, free the FDE array. */ - if (ob->fde_array && ob->fde_array != begin) - free (ob->fde_array); + if (ob == 0) + { + __gthread_mutex_unlock (&object_mutex); + return 0; + } - __gthread_mutex_unlock (&object_mutex); - return (void *) ob; - } - p = &((*p)->next); + if (!ob->fde_array || (void *)ob->fde_array == (void *)ob->fde_begin) + frame_init (ob); + + if (ob->fde_array && (void *)ob->fde_array != (void *)ob->fde_begin) + { + __gthread_mutex_unlock (&object_mutex); + + /* Standard binary search algorithm. */ + for (lo = 0, hi = ob->count; lo < hi; ) + { + size_t i = (lo + hi) / 2; + fde *f = ob->fde_array[i]; + + if (pc < f->pc_begin) + hi = i; + else if (pc >= f->pc_begin + f->pc_range) + lo = i + 1; + else + return f; + } } + else + { + /* Long slow labourious linear search, cos we've no memory. */ + fde *f; + + if (ob->fde_array) + { + fde **p = ob->fde_array; + + do + { + f = search_fdes (*p, pc); + if (f) + break; + p++; + } + while (*p); + } + else + f = search_fdes (ob->fde_begin, pc); - __gthread_mutex_unlock (&object_mutex); - abort (); -} + __gthread_mutex_unlock (&object_mutex); + return f; + } -void -__deregister_frame (void *begin) -{ - free (__deregister_frame_info (begin)); + return 0; } - diff --git a/gcc/unwind-dw2-fde.h b/gcc/unwind-dw2-fde.h new file mode 100644 index 00000000000..83b519a48b9 --- /dev/null +++ b/gcc/unwind-dw2-fde.h @@ -0,0 +1,120 @@ +/* Subroutines needed for unwinding stack frames for exception handling. */ +/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Contributed by Jason Merrill . + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +/* Describes data used to hold onto one shared object or object file. */ +struct object +{ + void *pc_begin; + void *pc_end; + struct dwarf_fde *fde_begin; + struct dwarf_fde **fde_array; + size_t count; + struct object *next; +}; + +struct dwarf_eh_bases +{ + void *tbase; + void *dbase; + void *func; +}; + + +extern void __register_frame_info (void *, struct object *); +extern void __register_frame (void *); +extern void __register_frame_info_table (void *, struct object *); +extern void __register_frame_table (void *); +extern void *__deregister_frame_info (void *); +extern void __deregister_frame (void *); + + +typedef int sword __attribute__ ((mode (SI))); +typedef unsigned int uword __attribute__ ((mode (SI))); +typedef unsigned int uaddr __attribute__ ((mode (pointer))); +typedef int saddr __attribute__ ((mode (pointer))); +typedef unsigned char ubyte; + +/* Terminology: + CIE - Common Information Element + FDE - Frame Descriptor Element + + There is one per function, and it describes where the function code + is located, and what the register lifetimes and stack layout are + within the function. + + The data structures are defined in the DWARF specfication, although + not in a very readable way (see LITERATURE). + + Every time an exception is thrown, the code needs to locate the FDE + for the current function, and starts to look for exception regions + from that FDE. This works in a two-level search: + a) in a linear search, find the shared image (i.e. DLL) containing + the PC + b) using the FDE table for that shared object, locate the FDE using + binary search (which requires the sorting). */ + +/* The first few fields of a CIE. The CIE_id field is 0 for a CIE, + to distinguish it from a valid FDE. FDEs are aligned to an addressing + unit boundary, but the fields within are unaligned. */ +struct dwarf_cie +{ + uword length; + sword CIE_id; + ubyte version; + unsigned char augmentation[]; +} __attribute__ ((packed, aligned (__alignof__ (void *)))); + +/* The first few fields of an FDE. */ +struct dwarf_fde +{ + uword length; + sword CIE_delta; + void * pc_begin; + uaddr pc_range; +} __attribute__ ((packed, aligned (__alignof__ (void *)))); + +typedef struct dwarf_fde fde; + +/* Locate the CIE for a given FDE. */ + +static inline struct dwarf_cie * +get_cie (struct dwarf_fde *f) +{ + return (void *)&f->CIE_delta - f->CIE_delta; +} + +static inline fde * +next_fde (fde *f) +{ + return (fde *)((char *)f + f->length + sizeof (f->length)); +} + +extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *); diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c new file mode 100644 index 00000000000..e2f20c9ee10 --- /dev/null +++ b/gcc/unwind-dw2.c @@ -0,0 +1,1217 @@ +/* DWARF2 exception handling and frame unwind runtime interface routines. + Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "tconfig.h" +#include "tsystem.h" +#include "dwarf2.h" +#include "unwind.h" +#include "unwind-dw2-fde.h" +#include "gthr.h" + + +#if !USING_SJLJ_EXCEPTIONS + +#ifndef STACK_GROWS_DOWNWARD +#define STACK_GROWS_DOWNWARD 0 +#else +#undef STACK_GROWS_DOWNWARD +#define STACK_GROWS_DOWNWARD 1 +#endif + +/* A target can override (perhaps for backward compatibility) how + many dwarf2 columns are unwound. */ +#ifndef DWARF_FRAME_REGISTERS +#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER +#endif + +/* This is the register and unwind state for a particular frame. */ +struct _Unwind_Context +{ + void *reg[DWARF_FRAME_REGISTERS+1]; + void *cfa; + void *ra; + void *lsda; + struct dwarf_eh_bases bases; + _Unwind_Word args_size; +}; + +/* Byte size of every register managed by these routines. */ +static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS]; + + +/* The result of interpreting the frame unwind info for a frame. + This is all symbolic at this point, as none of the values can + be resolved until the target pc is located. */ +typedef struct +{ + /* Each register save state can be described in terms of a CFA slot, + another register, or a location expression. */ + struct frame_state_reg_info + { + struct { + union { + unsigned int reg; + _Unwind_Sword offset; + unsigned char *exp; + } loc; + enum { + REG_UNSAVED, + REG_SAVED_OFFSET, + REG_SAVED_REG, + REG_SAVED_EXP, + } how; + } reg[DWARF_FRAME_REGISTERS+1]; + + /* Used to implement DW_CFA_remember_state. */ + struct frame_state_reg_info *prev; + } regs; + + /* The CFA can be described in terms of a reg+offset or a + location expression. */ + _Unwind_Sword cfa_offset; + _Unwind_Word cfa_reg; + unsigned char *cfa_exp; + enum { + CFA_UNSET, + CFA_REG_OFFSET, + CFA_EXP, + } cfa_how; + + /* The PC described by the current frame state. */ + void *pc; + + /* The information we care about from the CIE/FDE. */ + _Unwind_Personality_Fn personality; + signed int data_align; + unsigned int code_align; + unsigned char retaddr_column; + unsigned char addr_encoding; + unsigned char saw_z; + unsigned char saw_lsda; +} _Unwind_FrameState; + +/* Decode the unsigned LEB128 constant at BUF into the variable pointed to + by R, and return the new value of BUF. */ + +static unsigned char * +read_uleb128 (unsigned char *buf, _Unwind_Word *r) +{ + unsigned shift = 0; + _Unwind_Word result = 0; + + while (1) + { + unsigned char byte = *buf++; + result |= (byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + *r = result; + return buf; +} + +/* Decode the signed LEB128 constant at BUF into the variable pointed to + by R, and return the new value of BUF. */ + +static unsigned char * +read_sleb128 (unsigned char *buf, _Unwind_Sword *r) +{ + unsigned shift = 0; + _Unwind_Sword result = 0; + unsigned char byte; + + while (1) + { + byte = *buf++; + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + break; + } + if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) + result |= - (1 << shift); + + *r = result; + return buf; +} + +/* Read unaligned data from the instruction buffer. */ + +union unaligned +{ + void *p; + unsigned u2 __attribute__ ((mode (HI))); + unsigned u4 __attribute__ ((mode (SI))); + unsigned u8 __attribute__ ((mode (DI))); + signed s2 __attribute__ ((mode (HI))); + signed s4 __attribute__ ((mode (SI))); + signed s8 __attribute__ ((mode (DI))); +} __attribute__ ((packed)); + +static inline void * +read_pointer (void *p) { union unaligned *up = p; return up->p; } + +static inline int +read_1u (void *p) { return *(unsigned char *)p; } + +static inline int +read_1s (void *p) { return *(signed char *)p; } + +static inline int +read_2u (void *p) { union unaligned *up = p; return up->u2; } + +static inline int +read_2s (void *p) { union unaligned *up = p; return up->s2; } + +static inline unsigned int +read_4u (void *p) { union unaligned *up = p; return up->u4; } + +static inline int +read_4s (void *p) { union unaligned *up = p; return up->s4; } + +static inline unsigned long +read_8u (void *p) { union unaligned *up = p; return up->u8; } + +static inline unsigned long +read_8s (void *p) { union unaligned *up = p; return up->s8; } + +static unsigned char * +read_encoded_pointer (unsigned char *p, unsigned char encoding, + struct dwarf_eh_bases *bases, void **pptr) +{ + signed long val; + unsigned char *ret; + + switch (encoding & 0x0f) + { + case DW_EH_PE_absptr: + val = (_Unwind_Ptr) read_pointer (p); + ret = p + sizeof (void *); + break; + + case DW_EH_PE_uleb128: + ret = read_uleb128 (p, &val); + break; + case DW_EH_PE_sleb128: + ret = read_sleb128 (p, &val); + break; + + case DW_EH_PE_udata2: + val = read_2u (p); + ret = p + 2; + break; + case DW_EH_PE_udata4: + val = read_4u (p); + ret = p + 4; + break; + case DW_EH_PE_udata8: + val = read_8u (p); + ret = p + 8; + break; + + case DW_EH_PE_sdata2: + val = read_2s (p); + ret = p + 2; + break; + case DW_EH_PE_sdata4: + val = read_4s (p); + ret = p + 4; + break; + case DW_EH_PE_sdata8: + val = read_8s (p); + ret = p + 8; + break; + + default: + abort (); + } + + if (val != 0) + switch (encoding & 0xf0) + { + case DW_EH_PE_absptr: + break; + case DW_EH_PE_pcrel: + val += (_Unwind_Ptr) p; + break; + case DW_EH_PE_textrel: + val += (_Unwind_Ptr) bases->tbase; + break; + case DW_EH_PE_datarel: + val += (_Unwind_Ptr) bases->dbase; + break; + case DW_EH_PE_funcrel: + val += (_Unwind_Ptr) bases->func; + break; + default: + abort (); + } + + *pptr = (void *) (_Unwind_Ptr) val; + return ret; +} + +/* Get the value of register REG as saved in CONTEXT. */ + +inline _Unwind_Word +_Unwind_GetGR (struct _Unwind_Context *context, int index) +{ + /* This will segfault if the register hasn't been saved. */ + return * (_Unwind_Word *) context->reg[index]; +} + +/* Overwrite the saved value for register REG in CONTEXT with VAL. */ + +inline void +_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) +{ + * (_Unwind_Word *) context->reg[index] = val; +} + +/* Retrieve the return address for CONTEXT. */ + +inline _Unwind_Ptr +_Unwind_GetIP (struct _Unwind_Context *context) +{ + return (_Unwind_Ptr) context->ra; +} + +/* Overwrite the return address for CONTEXT with VAL. */ + +inline void +_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val) +{ + context->ra = (void *) val; +} + +void * +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) +{ + return context->lsda; +} + +_Unwind_Ptr +_Unwind_GetRegionStart (struct _Unwind_Context *context) +{ + return (_Unwind_Ptr) context->bases.func; +} + + +/* Extract any interesting information from the CIE for the translation + unit F belongs to. Return a pointer to the byte after the augmentation, + or NULL if we encountered an undecipherable augmentation. */ + +static unsigned char * +extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, + _Unwind_FrameState *fs) +{ + unsigned char *aug = cie->augmentation; + unsigned char *p = aug + strlen (aug) + 1; + unsigned char *ret = NULL; + _Unwind_Word code_align; + _Unwind_Sword data_align; + + /* Immediately following the augmentation are the code and + data alignment and return address column. */ + p = read_uleb128 (p, &code_align); + p = read_sleb128 (p, &data_align); + fs->code_align = code_align; + fs->data_align = data_align; + fs->retaddr_column = *p++; + + /* If the augmentation starts with 'z', then a uleb128 immediately + follows containing the length of the augmentation field following + the size. */ + if (*aug == 'z') + { + _Unwind_Word i; + p = read_uleb128 (p, &i); + ret = p + i; + + fs->saw_z = 1; + ++aug; + } + + /* Iterate over recognized augmentation subsequences. */ + while (*aug != '\0') + { + /* "eh" was used by g++ v2; recognize and skip. */ + if (aug[0] == 'e' && aug[1] == 'h') + { + p += sizeof (void *); + aug += 2; + } + + /* "R" indicates a byte indicating how addresses are encoded. */ + else if (aug[0] == 'R') + { + fs->addr_encoding = *p++; + aug += 1; + } + + /* "P" indicates a personality routine in the CIE augmentation + and an lsda pointer in the FDE augmentation. */ + else if (aug[0] == 'P') + { + p = read_encoded_pointer (p, fs->addr_encoding, &context->bases, + (void **) &fs->personality); + fs->saw_lsda = 1; + aug += 1; + } + + /* Otherwise we have an unknown augmentation string. + Bail unless we saw a 'z' prefix. */ + else + return ret; + } + + return ret ? ret : p; +} + + +/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL + onto the stack to start. */ + +static _Unwind_Word +execute_stack_op (unsigned char *op_ptr, unsigned char *op_end, + struct _Unwind_Context *context, _Unwind_Word initial) +{ + _Unwind_Word stack[64]; /* ??? Assume this is enough. */ + int stack_elt; + + stack[0] = initial; + stack_elt = 1; + + while (op_ptr < op_end) + { + enum dwarf_location_atom op = *op_ptr++; + _Unwind_Word result, reg; + _Unwind_Sword offset; + + switch (op) + { + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + result = op - DW_OP_lit0; + break; + + case DW_OP_addr: + result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr); + op_ptr += sizeof (void *); + break; + + case DW_OP_const1u: + result = read_1u (op_ptr); + op_ptr += 1; + break; + case DW_OP_const1s: + result = read_1s (op_ptr); + op_ptr += 1; + break; + case DW_OP_const2u: + result = read_2u (op_ptr); + op_ptr += 2; + break; + case DW_OP_const2s: + result = read_2s (op_ptr); + op_ptr += 2; + break; + case DW_OP_const4u: + result = read_4u (op_ptr); + op_ptr += 4; + break; + case DW_OP_const4s: + result = read_4s (op_ptr); + op_ptr += 4; + break; + case DW_OP_const8u: + result = read_8u (op_ptr); + op_ptr += 8; + break; + case DW_OP_const8s: + result = read_8s (op_ptr); + op_ptr += 8; + break; + case DW_OP_constu: + op_ptr = read_uleb128 (op_ptr, &result); + break; + case DW_OP_consts: + op_ptr = read_sleb128 (op_ptr, &offset); + result = offset; + break; + + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + result = _Unwind_GetGR (context, op - DW_OP_reg0); + break; + case DW_OP_regx: + op_ptr = read_uleb128 (op_ptr, ®); + result = _Unwind_GetGR (context, reg); + break; + + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + op_ptr = read_sleb128 (op_ptr, &offset); + result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset; + break; + case DW_OP_bregx: + op_ptr = read_uleb128 (op_ptr, ®); + op_ptr = read_sleb128 (op_ptr, &offset); + result = _Unwind_GetGR (context, reg) + offset; + break; + + case DW_OP_dup: + if (stack_elt < 1) + abort (); + result = stack[stack_elt - 1]; + break; + + case DW_OP_drop: + if (--stack_elt < 0) + abort (); + goto no_push; + + case DW_OP_pick: + offset = *op_ptr++; + if (offset >= stack_elt - 1) + abort (); + result = stack[stack_elt - 1 - offset]; + break; + + case DW_OP_over: + if (stack_elt < 2) + abort (); + result = stack[stack_elt - 2]; + break; + + case DW_OP_rot: + { + _Unwind_Word t1, t2, t3; + + if (stack_elt < 3) + abort (); + t1 = stack[stack_elt - 1]; + t2 = stack[stack_elt - 2]; + t3 = stack[stack_elt - 3]; + stack[stack_elt - 1] = t2; + stack[stack_elt - 2] = t3; + stack[stack_elt - 3] = t1; + goto no_push; + } + + case DW_OP_deref: + case DW_OP_deref_size: + case DW_OP_abs: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_plus_uconst: + /* Unary operations. */ + if (--stack_elt < 0) + abort (); + result = stack[stack_elt]; + + switch (op) + { + case DW_OP_deref: + { + void *ptr = (void *)(_Unwind_Ptr) result; + result = (_Unwind_Ptr) read_pointer (ptr); + } + break; + + case DW_OP_deref_size: + { + void *ptr = (void *)(_Unwind_Ptr) result; + switch (*op_ptr++) + { + case 1: + result = read_1u (ptr); + break; + case 2: + result = read_2u (ptr); + break; + case 4: + result = read_4u (ptr); + break; + case 8: + result = read_8u (ptr); + break; + default: + abort (); + } + } + break; + + case DW_OP_abs: + if ((_Unwind_Sword) result < 0) + result = -result; + break; + case DW_OP_neg: + result = -result; + break; + case DW_OP_not: + result = ~result; + break; + case DW_OP_plus_uconst: + op_ptr = read_uleb128 (op_ptr, ®); + result += reg; + break; + } + break; + + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_or: + case DW_OP_plus: + case DW_OP_le: + case DW_OP_ge: + case DW_OP_eq: + case DW_OP_lt: + case DW_OP_gt: + case DW_OP_ne: + { + /* Binary operations. */ + _Unwind_Word first, second; + if ((stack_elt -= 2) < 0) + abort (); + second = stack[stack_elt]; + first = stack[stack_elt + 1]; + + switch (op) + { + case DW_OP_and: + result = second & first; + break; + case DW_OP_div: + result = (_Unwind_Sword)second / (_Unwind_Sword)first; + break; + case DW_OP_minus: + result = second - first; + break; + case DW_OP_mod: + result = (_Unwind_Sword)second % (_Unwind_Sword)first; + break; + case DW_OP_mul: + result = second * first; + break; + case DW_OP_or: + result = second | first; + break; + case DW_OP_plus: + result = second + first; + break; + case DW_OP_shl: + result = second << first; + break; + case DW_OP_shr: + result = second >> first; + break; + case DW_OP_shra: + result = (_Unwind_Sword)second >> first; + break; + case DW_OP_xor: + result = second ^ first; + break; + case DW_OP_le: + result = (_Unwind_Sword)first <= (_Unwind_Sword)second; + break; + case DW_OP_ge: + result = (_Unwind_Sword)first >= (_Unwind_Sword)second; + break; + case DW_OP_eq: + result = (_Unwind_Sword)first == (_Unwind_Sword)second; + break; + case DW_OP_lt: + result = (_Unwind_Sword)first < (_Unwind_Sword)second; + break; + case DW_OP_gt: + result = (_Unwind_Sword)first > (_Unwind_Sword)second; + break; + case DW_OP_ne: + result = (_Unwind_Sword)first != (_Unwind_Sword)second; + break; + } + } + break; + + case DW_OP_skip: + offset = read_2s (op_ptr); + op_ptr += 2; + op_ptr += offset; + goto no_push; + + case DW_OP_bra: + if (--stack_elt < 0) + abort (); + offset = read_2s (op_ptr); + op_ptr += 2; + if (stack[stack_elt] != 0) + op_ptr += offset; + goto no_push; + + case DW_OP_nop: + goto no_push; + + default: + abort (); + } + + /* Most things push a result value. */ + if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack)) + abort (); + stack[++stack_elt] = result; + no_push:; + } + + /* We were executing this program to get a value. It should be + at top of stack. */ + if (--stack_elt < 0) + abort (); + return stack[stack_elt]; +} + + +/* Decode DWARF 2 call frame information. Takes pointers the + instruction sequence to decode, current register information and + CIE info, and the PC range to evaluate. */ + +static void +execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end, + struct _Unwind_Context *context, _Unwind_FrameState *fs) +{ + struct frame_state_reg_info *unused_rs = NULL; + + /* Don't allow remember/restore between CIE and FDE programs. */ + fs->regs.prev = NULL; + + while (insn_ptr < insn_end && fs->pc < context->ra) + { + unsigned char insn = *insn_ptr++; + _Unwind_Word reg, uoffset; + _Unwind_Sword offset; + + if (insn & DW_CFA_advance_loc) + fs->pc += (insn & 0x3f) * fs->code_align; + else if (insn & DW_CFA_offset) + { + reg = insn & 0x3f; + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + offset = (_Unwind_Sword)uoffset * fs->data_align; + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } + else if (insn & DW_CFA_restore) + { + reg = insn & 0x3f; + fs->regs.reg[reg].how = REG_UNSAVED; + } + else switch (insn) + { + case DW_CFA_set_loc: + insn_ptr = read_encoded_pointer (insn_ptr, fs->addr_encoding, + &context->bases, &fs->pc); + break; + + case DW_CFA_advance_loc1: + fs->pc += read_1u (insn_ptr); + insn_ptr += 1; + break; + case DW_CFA_advance_loc2: + fs->pc += read_2u (insn_ptr); + insn_ptr += 2; + break; + case DW_CFA_advance_loc4: + fs->pc += read_4u (insn_ptr); + insn_ptr += 4; + break; + + case DW_CFA_offset_extended: + insn_ptr = read_uleb128 (insn_ptr, ®); + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + offset = (_Unwind_Sword)uoffset * fs->data_align; + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + break; + + case DW_CFA_restore_extended: + insn_ptr = read_uleb128 (insn_ptr, ®); + fs->regs.reg[reg].how = REG_UNSAVED; + break; + + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_nop: + break; + + case DW_CFA_register: + { + _Unwind_Word reg2; + insn_ptr = read_uleb128 (insn_ptr, ®); + insn_ptr = read_uleb128 (insn_ptr, ®2); + fs->regs.reg[reg].how = REG_SAVED_REG; + fs->regs.reg[reg].loc.reg = reg2; + } + break; + + case DW_CFA_remember_state: + { + struct frame_state_reg_info *new_rs; + if (unused_rs) + { + new_rs = unused_rs; + unused_rs = unused_rs->prev; + } + else + new_rs = alloca (sizeof (struct frame_state_reg_info)); + + *new_rs = fs->regs; + fs->regs.prev = new_rs; + } + break; + + case DW_CFA_restore_state: + { + struct frame_state_reg_info *old_rs = fs->regs.prev; + fs->regs = *old_rs; + old_rs->prev = unused_rs; + unused_rs = old_rs; + } + break; + + case DW_CFA_def_cfa: + insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg); + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + fs->cfa_offset = uoffset; + fs->cfa_how = CFA_REG_OFFSET; + break; + + case DW_CFA_def_cfa_register: + insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg); + fs->cfa_how = CFA_REG_OFFSET; + break; + + case DW_CFA_def_cfa_offset: + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + fs->cfa_offset = uoffset; + /* cfa_how deliberately not set. */ + break; + + case DW_CFA_def_cfa_expression: + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + fs->cfa_exp = insn_ptr; + fs->cfa_how = CFA_EXP; + insn_ptr += uoffset; + break; + + case DW_CFA_expression: + insn_ptr = read_uleb128 (insn_ptr, ®); + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + fs->regs.reg[reg].how = REG_SAVED_EXP; + fs->regs.reg[reg].loc.exp = insn_ptr; + insn_ptr += uoffset; + break; + + /* From the 2.1 draft. */ + case DW_CFA_offset_extended_sf: + insn_ptr = read_uleb128 (insn_ptr, ®); + insn_ptr = read_sleb128 (insn_ptr, &offset); + offset *= fs->data_align; + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + break; + + case DW_CFA_def_cfa_sf: + insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg); + insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset); + fs->cfa_how = CFA_REG_OFFSET; + break; + + case DW_CFA_def_cfa_offset_sf: + insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_offset); + /* cfa_how deliberately not set. */ + break; + + case DW_CFA_GNU_window_save: + /* ??? Hardcoded for SPARC register window configuration. */ + for (reg = 16; reg < 32; ++reg) + { + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *); + } + break; + + case DW_CFA_GNU_args_size: + insn_ptr = read_uleb128 (insn_ptr, &context->args_size); + break; + + case DW_CFA_GNU_negative_offset_extended: + /* Obsoleted by DW_CFA_offset_extended_sf, but used by + older PowerPC code. */ + insn_ptr = read_uleb128 (insn_ptr, ®); + insn_ptr = read_uleb128 (insn_ptr, &uoffset); + offset = (_Unwind_Sword)uoffset * fs->data_align; + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = -offset; + break; + + default: + abort (); + } + } +} + +static _Unwind_Reason_Code +uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) +{ + struct dwarf_fde *fde; + struct dwarf_cie *cie; + unsigned char *aug, *insn, *end; + + memset (fs, 0, sizeof (*fs)); + context->args_size = 0; + context->lsda = 0; + + fde = _Unwind_Find_FDE (context->ra - 1, &context->bases); + if (fde == NULL) + { + /* Couldn't find frame unwind info for this function. Try a + target-specific fallback mechanism. This will necessarily + not profide a personality routine or LSDA. */ +#ifdef MD_FALLBACK_FRAME_STATE_FOR + MD_FALLBACK_FRAME_STATE_FOR (context, fs, success); + return _URC_END_OF_STACK; + success: + return _URC_NO_REASON; +#else + return _URC_END_OF_STACK; +#endif + } + + context->bases.func = fde->pc_begin; + fs->pc = fde->pc_begin; + + cie = get_cie (fde); + insn = extract_cie_info (cie, context, fs); + if (insn == NULL) + /* CIE contained unknown augmentation. */ + return _URC_FATAL_PHASE1_ERROR; + + /* First decode all the insns in the CIE. */ + end = (unsigned char *) next_fde ((struct dwarf_fde *) cie); + execute_cfa_program (insn, end, context, fs); + + /* Locate augmentation for the fde. */ + aug = (unsigned char *)fde + sizeof (*fde); + insn = NULL; + if (fs->saw_z) + { + _Unwind_Word i; + aug = read_uleb128 (aug, &i); + insn = aug + i; + } + if (fs->saw_lsda) + aug = read_encoded_pointer (aug, fs->addr_encoding, + &context->bases, &context->lsda); + + /* Then the insns in the FDE up to our target PC. */ + if (insn == NULL) + insn = aug; + end = (unsigned char *) next_fde (fde); + execute_cfa_program (insn, end, context, fs); + + return _URC_NO_REASON; +} + + +static void +uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) +{ + struct _Unwind_Context orig_context = *context; + void *cfa; + long i; + + /* Compute this frame's CFA. */ + switch (fs->cfa_how) + { + case CFA_REG_OFFSET: + /* Special handling here: Many machines do not use a frame pointer, + and track the CFA only through offsets from the stack pointer from + one frame to the next. In this case, the stack pointer is never + stored, so it has no saved address in the context. What we do + have is the CFA from the previous stack frame. */ + if (context->reg[fs->cfa_reg] == NULL) + cfa = context->cfa; + else + cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg); + cfa += fs->cfa_offset; + break; + + case CFA_EXP: + /* ??? No way of knowing what register number is the stack pointer + to do the same sort of handling as above. Assume that if the + CFA calculation is so complicated as to require a stack program + that this will not be a problem. */ + { + unsigned char *exp = fs->cfa_exp; + _Unwind_Word len; + + exp = read_uleb128 (exp, &len); + cfa = (void *) (_Unwind_Ptr) + execute_stack_op (exp, exp + len, context, 0); + break; + } + + default: + abort (); + } + context->cfa = cfa; + + /* Compute the addresses of all registers saved in this frame. */ + for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i) + switch (fs->regs.reg[i].how) + { + case REG_UNSAVED: + break; + case REG_SAVED_OFFSET: + context->reg[i] = cfa + fs->regs.reg[i].loc.offset; + break; + case REG_SAVED_REG: + context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg]; + break; + case REG_SAVED_EXP: + { + unsigned char *exp = fs->regs.reg[i].loc.exp; + _Unwind_Word len; + _Unwind_Ptr val; + + exp = read_uleb128 (exp, &len); + val = execute_stack_op (exp, exp + len, &orig_context, + (_Unwind_Ptr) cfa); + context->reg[i] = (void *) val; + } + break; + } +} + +static void +uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) +{ + uw_update_context_1 (context, fs); + + /* Compute the return address now, since the return address column + can change from frame to frame. */ + context->ra = __builtin_extract_return_addr + ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column)); +} + +/* Fill in CONTEXT for top-of-stack. The only valid registers at this + level will be the return address and the CFA. */ + +#define uw_init_context(CONTEXT) \ +do { \ + /* Do any necessary initialization to access arbitrary stack frames. \ + On the SPARC, this means flushing the register windows. */ \ + __builtin_unwind_init (); \ + uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \ + __builtin_return_address (0)); \ +} while (0) + +static void +uw_init_context_1 (struct _Unwind_Context *context, + void *outer_cfa, void *outer_ra) +{ + void *ra = __builtin_extract_return_addr (__builtin_return_address (0)); + _Unwind_FrameState fs; + + memset (context, 0, sizeof (struct _Unwind_Context)); + context->ra = ra; + + if (uw_frame_state_for (context, &fs) != _URC_NO_REASON) + abort (); + + /* Force the frame state to use the known cfa value. */ + context->cfa = outer_cfa; + fs.cfa_how = CFA_REG_OFFSET; + fs.cfa_reg = 0; + fs.cfa_offset = 0; + + uw_update_context_1 (context, &fs); + + /* If the return address column was saved in a register in the + initialization context, then we can't see it in the given + call frame data. So have the initialization context tell us. */ + context->ra = __builtin_extract_return_addr (outer_ra); +} + + +/* Install TARGET into CURRENT so that we can return to it. This is a + macro because __builtin_eh_return must be invoked in the context of + our caller. */ + +#define uw_install_context(CURRENT, TARGET) \ +do { \ + long offset = uw_install_context_1 ((CURRENT), (TARGET)); \ + void *handler = __builtin_frob_return_addr ((TARGET)->ra); \ + __builtin_eh_return (offset, handler); \ +} while (0) + +static inline void +init_dwarf_reg_size_table (void) +{ + __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table); +} + +static long +uw_install_context_1 (struct _Unwind_Context *current, + struct _Unwind_Context *target) +{ + long i; + +#if __GTHREADS + { + static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT; + if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0 + || dwarf_reg_size_table[0] == 0) + init_dwarf_reg_size_table (); + } +#else + if (dwarf_reg_size_table[0] == 0) + init_dwarf_reg_size_table (); +#endif + + for (i = 0; i < DWARF_FRAME_REGISTERS; ++i) + { + void *c = current->reg[i]; + void *t = target->reg[i]; + if (t && c && t != c) + memcpy (c, t, dwarf_reg_size_table[i]); + } + + /* We adjust SP by the difference between CURRENT and TARGET's CFA. */ + if (STACK_GROWS_DOWNWARD) + return target->cfa - current->cfa + target->args_size; + else + return current->cfa - target->cfa - target->args_size; +} + +static inline _Unwind_Ptr +uw_identify_context (struct _Unwind_Context *context) +{ + return _Unwind_GetIP (context); +} + + +#include "unwind.inc" + +#endif /* !USING_SJLJ_EXCEPTIONS */ diff --git a/gcc/unwind-sjlj.c b/gcc/unwind-sjlj.c new file mode 100644 index 00000000000..662968bd001 --- /dev/null +++ b/gcc/unwind-sjlj.c @@ -0,0 +1,259 @@ +/* DWARF2 exception handling and frame unwind runtime interface routines. + Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "tconfig.h" +#include "tsystem.h" +#include "unwind.h" +#include "gthr.h" + +#if USING_SJLJ_EXCEPTIONS + +#ifdef DONT_USE_BUILTIN_SETJMP +#include +#else +#define setjmp __builtin_setjmp +#define longjmp __builtin_longjmp +#endif + +/* This structure is allocated on the stack of the target function. + This must match the definition created in except.c:init_eh. */ +struct SjLj_Function_Context +{ + /* This is the chain through all registered contexts. It is + filled in by _Unwind_SjLj_Register. */ + struct SjLj_Function_Context *prev; + + /* This is assigned in by the target function before every call + to the index of the call site in the lsda. It is assigned by + the personality routine to the landing pad index. */ + int call_site; + + /* This is how data is returned from the personality routine to + the target function's handler. */ + _Unwind_Word data[4]; + + /* These are filled in once by the target function before any + exceptions are expected to be handled. */ + _Unwind_Personality_Fn personality; + void *lsda; + +#ifdef DONT_USE_BUILTIN_SETJMP + /* We don't know what sort of alignment requirements the system + jmp_buf has. We over estimated in except.c, and now we have + to match that here just in case the system *didn't* have more + restrictive requirements. */ + jmp_buf jbuf __attribute__((aligned)); +#else + void *jbuf[]; +#endif +}; + +struct _Unwind_Context +{ + struct SjLj_Function_Context *fc; +}; + +typedef struct +{ + _Unwind_Personality_Fn personality; +} _Unwind_FrameState; + + +/* Manage the chain of registered function contexts. */ + +/* Single threaded fallback chain. */ +static struct SjLj_Function_Context *fc_static; + +#if __GTHREADS +static __gthread_key_t fc_key; +static int use_fc_key = -1; + +static void +fc_key_dtor (void *ptr) +{ + __gthread_key_dtor (fc_key, ptr); +} + +static void +fc_key_init (void) +{ + use_fc_key = __gthread_key_create (&fc_key, fc_key_dtor) == 0; +} + +static void +fc_key_init_once (void) +{ + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + if (__gthread_once (&once, fc_key_init) != 0 || use_fc_key < 0) + use_fc_key = 0; +} +#endif + +void +_Unwind_SjLj_Register (struct SjLj_Function_Context *fc) +{ +#if __GTHREADS + if (use_fc_key < 0) + fc_key_init_once (); + + if (use_fc_key) + { + fc->prev = __gthread_getspecific (fc_key); + __gthread_setspecific (fc_key, fc); + } + else +#endif + { + fc->prev = fc_static; + fc_static = fc; + } +} + +static inline struct SjLj_Function_Context * +_Unwind_SjLj_GetContext (void) +{ +#if __GTHREADS + if (use_fc_key < 0) + fc_key_init_once (); + + if (use_fc_key) + return __gthread_getspecific (fc_key); +#endif + return fc_static; +} + +static inline void +_Unwind_SjLj_SetContext (struct SjLj_Function_Context *fc) +{ +#if __GTHREADS + if (use_fc_key < 0) + fc_key_init_once (); + + if (use_fc_key) + __gthread_setspecific (fc_key, fc); + else +#endif + fc_static = fc; +} + +void +_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc) +{ + _Unwind_SjLj_SetContext (fc->prev); +} + + +/* Get/set the return data value at INDEX in CONTEXT. */ + +_Unwind_Word +_Unwind_GetGR (struct _Unwind_Context *context, int index) +{ + return context->fc->data[index]; +} + +void +_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) +{ + context->fc->data[index] = val; +} + +/* Get the call-site index as saved in CONTEXT. */ + +_Unwind_Ptr +_Unwind_GetIP (struct _Unwind_Context *context) +{ + return context->fc->call_site + 1; +} + +/* Set the return landing pad index in CONTEXT. */ + +void +_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val) +{ + context->fc->call_site = val - 1; +} + +void * +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) +{ + return context->fc->lsda; +} + +_Unwind_Ptr +_Unwind_GetRegionStart (struct _Unwind_Context *context) +{ + return 0; +} + + +static inline _Unwind_Reason_Code +uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) +{ + if (context->fc == NULL) + { + fs->personality = NULL; + return _URC_END_OF_STACK; + } + else + { + fs->personality = context->fc->personality; + return _URC_NO_REASON; + } +} + +static inline void +uw_update_context (struct _Unwind_Context *context, + _Unwind_FrameState *fs __attribute__((unused)) ) +{ + context->fc = context->fc->prev; +} + +static inline void +uw_init_context (struct _Unwind_Context *context) +{ + context->fc = _Unwind_SjLj_GetContext (); +} + +/* ??? There appear to be bugs in integrate.c wrt __builtin_longjmp and + virtual-stack-vars. An inline version of this segfaults on Sparc. */ +#define uw_install_context(CURRENT, TARGET) \ + do { \ + _Unwind_SjLj_SetContext ((TARGET)->fc); \ + longjmp ((TARGET)->fc->jbuf, 1); \ + } while (0) + + +static inline _Unwind_Ptr +uw_identify_context (struct _Unwind_Context *context) +{ + return (_Unwind_Ptr) context->fc; +} + + +/* Play games with unwind symbols so that we can have call frame + and sjlj symbols in the same shared library. Not that you can + use them simultaneously... */ +#define _Unwind_RaiseException _Unwind_SjLj_RaiseException +#define _Unwind_ForcedUnwind _Unwind_SjLj_ForcedUnwind +#define _Unwind_Resume _Unwind_SjLj_Resume + +#include "unwind.inc" + +#endif /* USING_SJLJ_EXCEPTIONS */ diff --git a/gcc/unwind.h b/gcc/unwind.h new file mode 100644 index 00000000000..8df0930e917 --- /dev/null +++ b/gcc/unwind.h @@ -0,0 +1,166 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This is derived from the C++ ABI for IA-64. Where we diverge + for cross-architecture compatibility are noted with "@@@". */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Level 1: Base ABI */ + +/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is + inefficient for 32-bit and smaller machines. */ +typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); +typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); + +/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and + consumer of an exception. We'll go along with this for now even on + 32-bit machines. We'll need to provide some other option for + 16-bit machines and for machines with > 8 bits per byte. */ +typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); + +/* The unwind interface uses reason codes in several contexts to + identify the reasons for failures or other actions. */ +typedef enum +{ + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 +} _Unwind_Reason_Code; + + +/* The unwind interface uses a pointer to an exception header object + as its representation of an exception being thrown. In general, the + full representation of an exception object is language- and + implementation-specific, but it will be prefixed by a header + understood by the unwind interface. */ + +struct _Unwind_Exception; + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +struct _Unwind_Exception +{ + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + + /* @@@ The IA-64 ABI says that this structure must be double-word aligned. + Taking that literally does not make much sense generically. Instead we + provide the maximum alignment required by any type for the machine. */ +} __attribute__((__aligned__)); + + +/* The ACTIONS argument to the personality routine is a bitwise OR of one + or more of the following constants. */ +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 + +/* This is an opaque type used to refer to a system-specific data + structure used by the system unwinder. This context is created and + destroyed by the system, and passed to the personality routine + during unwinding. */ +struct _Unwind_Context; + +/* Raise an exception, passing along the given exception object. */ +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); + +/* Raise an exception for forced unwinding. */ + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, + void *); + +/* Helper to invoke the exception_cleanup routine. */ +extern void _Unwind_DeleteException (struct _Unwind_Exception *); + +/* Resume propagation of an existing exception. This is used after + e.g. executing cleanup code, and not to implement rethrowing. */ +extern void _Unwind_Resume (struct _Unwind_Exception *); + +/* These functions are used for communicating information about the unwind + context (i.e. the unwind descriptors and the user register state) between + the unwind library and the personality routine and landing pad. Only + selected registers maybe manipulated. */ + +extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); + +extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); + +extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); + +extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *); + + +/* The personality routine is the function in the C++ (or other language) + runtime library which serves as an interface between the system unwind + library and language-specific exception handling semantics. It is + specific to the code fragment described by an unwind info block, and + it is always referenced via the pointer in the unwind info block, and + hence it has no ABI-specified name. + + Note that this implies that two different C++ implementations can + use different names, and have different contents in the language + specific data area. Moreover, that the language specific data + area contains no version info because name of the function invoked + provides more effective versioning by detecting at link time the + lack of code to handle the different data format. */ + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +/* @@@ The following alternate entry points are for setjmp/longjmp + based unwinding. */ + +struct SjLj_Function_Context; +extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *); +extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *); + +extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException + (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind + (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); +extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); + +#ifdef __cplusplus +} +#endif diff --git a/gcc/unwind.inc b/gcc/unwind.inc new file mode 100644 index 00000000000..ba315361309 --- /dev/null +++ b/gcc/unwind.inc @@ -0,0 +1,232 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This is derived from the C++ ABI for IA-64. Where we diverge + for cross-architecture compatibility are noted with "@@@". + This file is included from unwind-dw2.c or unwind-ia64.c. */ + +/* Subroutine of _Unwind_RaiseException also invoked from _Unwind_Resume. + + Unwind the stack calling the personality routine to find both the + exception handler and intermediary cleanup code. We'll only locate + the first such frame here. Cleanup code will call back into + _Unwind_Resume and we'll continue Phase 2 there. */ + +static _Unwind_Reason_Code +_Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc, + struct _Unwind_Context *context) +{ + _Unwind_Reason_Code code; + + while (1) + { + _Unwind_FrameState fs; + int match_handler; + + code = uw_frame_state_for (context, &fs); + + /* Identify when we've reached the designated handler context. */ + match_handler = (uw_identify_context (context) == exc->private_2 + ? _UA_HANDLER_FRAME : 0); + + if (code != _URC_NO_REASON) + /* Some error encountered. Ususally the unwinder doesn't + diagnose these and merely crashes. */ + return _URC_FATAL_PHASE2_ERROR; + + /* Unwind successful. Run the personality routine, if any. */ + if (fs.personality) + { + code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler, + exc->exception_class, exc, context); + if (code == _URC_INSTALL_CONTEXT) + break; + if (code != _URC_CONTINUE_UNWIND) + return _URC_FATAL_PHASE2_ERROR; + } + + /* Don't let us unwind past the handler context. */ + if (match_handler) + abort (); + + uw_update_context (context, &fs); + } + + return code; +} + + +/* Raise an exception, passing along the given exception object. */ + +_Unwind_Reason_Code +_Unwind_RaiseException(struct _Unwind_Exception *exc) +{ + struct _Unwind_Context this_context, cur_context; + _Unwind_Reason_Code code; + + uw_init_context (&this_context); + cur_context = this_context; + + /* Phase 1: Search. Unwind the stack, calling the personality routine + with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */ + while (1) + { + _Unwind_FrameState fs; + + code = uw_frame_state_for (&cur_context, &fs); + + if (code == _URC_END_OF_STACK) + /* Hit end of stack with no handler found. */ + return _URC_END_OF_STACK; + + if (code != _URC_NO_REASON) + /* Some error encountered. Ususally the unwinder doesn't + diagnose these and merely crashes. */ + return _URC_FATAL_PHASE1_ERROR; + + /* Unwind successful. Run the personality routine, if any. */ + if (fs.personality) + { + code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class, + exc, &cur_context); + if (code == _URC_HANDLER_FOUND) + break; + else if (code != _URC_CONTINUE_UNWIND) + return _URC_FATAL_PHASE1_ERROR; + } + + uw_update_context (&cur_context, &fs); + } + + /* Indicate to _Unwind_Resume and associated subroutines that this + is not a forced unwind. Further, note where we found a handler. */ + exc->private_1 = 0; + exc->private_2 = uw_identify_context (&cur_context); + + cur_context = this_context; + code = _Unwind_RaiseException_Phase2 (exc, &cur_context); + if (code != _URC_INSTALL_CONTEXT) + return code; + + uw_install_context (&this_context, &cur_context); +} + + +/* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume. */ + +static _Unwind_Reason_Code +_Unwind_ForcedUnwind_Phase2(struct _Unwind_Exception *exc, + struct _Unwind_Context *context) +{ + _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) exc->private_1; + void *stop_argument = (void *) exc->private_2; + _Unwind_Reason_Code code, stop_code; + + while (1) + { + _Unwind_FrameState fs; + + code = uw_frame_state_for (context, &fs); + if (code != _URC_NO_REASON && code != _URC_END_OF_STACK) + return _URC_FATAL_PHASE2_ERROR; + + /* Unwind successful. */ + stop_code = (*stop) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE, + exc->exception_class, exc, context, stop_argument); + if (stop_code != _URC_NO_REASON) + return _URC_FATAL_PHASE2_ERROR; + + /* Stop didn't want to do anything. Invoke the personality + handler, if applicable, to run cleanups. */ + if (code == _URC_END_OF_STACK) + break; + + if (fs.personality) + { + code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE, + exc->exception_class, exc, context); + if (code == _URC_INSTALL_CONTEXT) + break; + if (code != _URC_CONTINUE_UNWIND) + return _URC_FATAL_PHASE2_ERROR; + } + + uw_update_context (context, &fs); + } + + return code; +} + + +/* Raise an exception for forced unwinding. */ + +_Unwind_Reason_Code +_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, + _Unwind_Stop_Fn stop, void * stop_argument) +{ + struct _Unwind_Context this_context, cur_context; + _Unwind_Reason_Code code; + + uw_init_context (&this_context); + cur_context = this_context; + + exc->private_1 = (_Unwind_Ptr) stop; + exc->private_2 = (_Unwind_Ptr) stop_argument; + + code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); + if (code != _URC_INSTALL_CONTEXT) + return code; + + uw_install_context (&this_context, &cur_context); +} + + +/* Resume propagation of an existing exception. This is used after + e.g. executing cleanup code, and not to implement rethrowing. */ + +void +_Unwind_Resume (struct _Unwind_Exception *exc) +{ + struct _Unwind_Context this_context, cur_context; + _Unwind_Reason_Code code; + + uw_init_context (&this_context); + cur_context = this_context; + + /* Choose between continuing to process _Unwind_RaiseException + or _Unwind_ForcedUnwind. */ + if (exc->private_1 == 0) + code = _Unwind_RaiseException_Phase2 (exc, &cur_context); + else + code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); + + if (code != _URC_INSTALL_CONTEXT) + abort (); + + uw_install_context (&this_context, &cur_context); +} + +/* A convenience function that calls the exception_cleanup field. */ + +void +_Unwind_DeleteException (struct _Unwind_Exception *exc) +{ + (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc); +} diff --git a/libjava/ChangeLog b/libjava/ChangeLog index d76ff6b13dd..103147bece5 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,29 @@ +2001-03-28 Richard Henderson + + IA-64 ABI Exception Handling: + * Makefile.am (GCC_UNWIND_INCLUDE): Rename from EH_COMMON_INCLUDE. + (AM_CXXFLAGS): -fnon-call-exceptions not -fasynchronous-exceptions. + Remove EXCEPTIONSPEC. + * configure.host (libgcj_sjlj): Remove. + * configure.in (EXCEPTIONSPEC): Remove. + (enable-sjlj-exceptions): Detect if not specified. + (GCC_UNWIND_INCLUDE): Rename from EH_COMMON_INCLUDE; change + what header we're looking for. + * libgcj.spec.in (jc1): Remove EXCEPTIONSPEC. + * Makefile.in, configure: Regenerate. + * exception.cc: Don't declare libgcc2 stuff. + (java_eh_info, _Jv_type_matcher, _Jv_exception_info): Remove. + (_Jv_eh_alloc, _Jv_eh_free, _Jv_setup_eh_info): Remove. + (win32_get_restart_frame): Remove. + (struct java_exception_header): New. + (__gcj_exception_class): New. + (get_exception_header_from_ue): New. + (_Jv_Throw): Rewrite for IA-64 ABI unwind routines. + (size_of_encoded_value, read_encoded_value): New. + (read_uleb128, read_sleb128, parse_lsda_header): New. + (get_ttype_entry, __gcj_personality_sj0): New. + * gcj/javaprims.h (_Jv_Sjlj_Throw): Remove. + 2001-03-27 Joerg Brunsmann * javax/naming/InitialContext.java (init): Fix typo. diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 60986803cb9..66b91e21245 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -87,18 +87,15 @@ LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(INCLUDES) $( JAVAC = $(GCJ_WITH_FLAGS) -C -EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@ +GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@ WARNINGS = -W -Wall ## We need _GNU_SOURCE defined for some Linux builds. It doesn't hurt ## to always define it. -## Note that we need -fasynchronous-exceptions because gcc is -## currently broken with respect to exception handling in leaf -## functions. -AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fasynchronous-exceptions \ +AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fnon-call-exceptions \ ## Some systems don't allow `$' in identifiers by default, so we force it. -fdollars-in-identifiers \ - @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE + @LIBGCJ_CXXFLAGS@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE if USING_GCC AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS) else @@ -112,7 +109,7 @@ LIBFFIINCS = -I$(top_srcdir)/../libffi/include -I$(MULTIBUILDTOP)../libffi/inclu INCLUDES = -I$(top_srcdir) -Iinclude -I$(top_srcdir)/include \ $(GCINCS) $(THREADINCS) $(INCLTDL) \ - $(EH_COMMON_INCLUDE) $(ZINCS) $(LIBFFIINCS) + $(GCC_UNWIND_INCLUDE) $(ZINCS) $(LIBFFIINCS) ## ################################################################ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 8a172f069a5..c5371f69e4a 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -153,12 +153,12 @@ LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(INCLUDES) $( JAVAC = $(GCJ_WITH_FLAGS) -C -EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@ +GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@ WARNINGS = -W -Wall -AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fasynchronous-exceptions \ +AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fnon-call-exceptions \ -fdollars-in-identifiers \ - @LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE + @LIBGCJ_CXXFLAGS@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE @USING_GCC_TRUE@AM_CFLAGS = @USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS) @USING_GCC_FALSE@AM_CFLAGS = @USING_GCC_FALSE@@LIBGCJ_CFLAGS@ @@ -170,7 +170,7 @@ LIBFFIINCS = -I$(top_srcdir)/../libffi/include -I$(MULTIBUILDTOP)../libffi/inclu INCLUDES = -I$(top_srcdir) -Iinclude -I$(top_srcdir)/include \ $(GCINCS) $(THREADINCS) $(INCLTDL) \ - $(EH_COMMON_INCLUDE) $(ZINCS) $(LIBFFIINCS) + $(GCC_UNWIND_INCLUDE) $(ZINCS) $(LIBFFIINCS) nat_files = $(nat_source_files:.cc=.lo) diff --git a/libjava/configure b/libjava/configure index 9126d8e1e41..71dd1aba863 100755 --- a/libjava/configure +++ b/libjava/configure @@ -43,7 +43,7 @@ ac_help="$ac_help ac_help="$ac_help --enable-interpreter enable interpreter" ac_help="$ac_help - --enable-sjlj-exceptions use setjmp/longjmp exceptions" + --enable-sjlj-exceptions force use of builtin_setjmp for exceptions" ac_help="$ac_help --disable-java-net disable java.net" ac_help="$ac_help @@ -77,7 +77,6 @@ program_suffix=NONE program_transform_name=s,x,x, silent= site= -sitefile= srcdir= target=NONE verbose= @@ -192,7 +191,6 @@ Configuration: --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages - --site-file=FILE use FILE as the site file --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX @@ -363,11 +361,6 @@ EOF -site=* | --site=* | --sit=*) site="$ac_optarg" ;; - -site-file | --site-file | --site-fil | --site-fi | --site-f) - ac_prev=sitefile ;; - -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) - sitefile="$ac_optarg" ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) @@ -533,16 +526,12 @@ fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. -if test -z "$sitefile"; then - if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -else - CONFIG_SITE="$sitefile" fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then @@ -630,7 +619,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:634: checking host system type" >&5 +echo "configure:623: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -651,7 +640,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:655: checking target system type" >&5 +echo "configure:644: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -669,7 +658,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:673: checking build system type" >&5 +echo "configure:662: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -692,7 +681,7 @@ test "$host_alias" != "$target_alias" && program_prefix=${target_alias}- echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:696: checking whether ln -s works" >&5 +echo "configure:685: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -738,7 +727,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:742: checking for a BSD compatible install" >&5 +echo "configure:731: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -791,7 +780,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:795: checking whether build environment is sane" >&5 +echo "configure:784: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -848,7 +837,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:852: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:841: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -881,12 +870,12 @@ else fi echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:885: checking for Cygwin environment" >&5 +echo "configure:874: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else @@ -914,19 +903,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:918: checking for mingw32 environment" >&5 +echo "configure:907: checking for mingw32 environment" >&5 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:919: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -974,7 +963,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:978: checking host system type" >&5 +echo "configure:967: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -1001,7 +990,7 @@ echo "$ac_t""$host" 1>&6 # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1005: checking for $ac_word" >&5 +echo "configure:994: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1031,7 +1020,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1035: checking for $ac_word" >&5 +echo "configure:1024: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1082,7 +1071,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1086: checking for $ac_word" >&5 +echo "configure:1075: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1115,7 +1104,7 @@ fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1119: checking whether we are using GNU C" >&5 +echo "configure:1108: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1124,7 +1113,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1128: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1117: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1143,7 +1132,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1147: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1136: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1179,7 +1168,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1183: checking for $ac_word" >&5 +echo "configure:1172: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1212,7 +1201,7 @@ test -n "$CXX" || CXX="gcc" echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 -echo "configure:1216: checking whether we are using GNU C++" >&5 +echo "configure:1205: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1221,7 +1210,7 @@ else yes; #endif EOF -if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1225: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1214: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no @@ -1240,7 +1229,7 @@ ac_test_CXXFLAGS="${CXXFLAGS+set}" ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 -echo "configure:1244: checking whether ${CXX-g++} accepts -g" >&5 +echo "configure:1233: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1293,7 +1282,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:1297: checking for working aclocal" >&5 +echo "configure:1286: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1306,7 +1295,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:1310: checking for working autoconf" >&5 +echo "configure:1299: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1319,7 +1308,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:1323: checking for working automake" >&5 +echo "configure:1312: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1332,7 +1321,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:1336: checking for working autoheader" >&5 +echo "configure:1325: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1345,7 +1334,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:1349: checking for working makeinfo" >&5 +echo "configure:1338: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1364,7 +1353,7 @@ fi # LIBGCJ_CONFIGURE, which doesn't work because that means that it will # be run before AC_CANONICAL_HOST. echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1368: checking build system type" >&5 +echo "configure:1357: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1385,7 +1374,7 @@ echo "$ac_t""$build" 1>&6 # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1389: checking for $ac_word" >&5 +echo "configure:1378: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1417,7 +1406,7 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1421: checking for $ac_word" >&5 +echo "configure:1410: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1449,7 +1438,7 @@ fi # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1453: checking for $ac_word" >&5 +echo "configure:1442: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1481,7 +1470,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1485: checking for $ac_word" >&5 +echo "configure:1474: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1526,7 +1515,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1530: checking for a BSD compatible install" >&5 +echo "configure:1519: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1580,7 +1569,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:1584: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:1573: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -1614,7 +1603,7 @@ if false; then echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:1618: checking for executable suffix" >&5 +echo "configure:1607: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1624,10 +1613,10 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:1628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:1617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *.c | *.o | *.obj) ;; *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; esac done @@ -1676,7 +1665,7 @@ LIBGCJ_JAVAFLAGS="${libgcj_javaflags}" # Only use libltdl for native builds. if test -z "${with_cross_host}"; then - case "$enable_ltdl_convenience" in + case $enable_ltdl_convenience in no) { echo "configure: error: this package needs a convenience libltdl" 1>&2; exit 1; } ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; @@ -1700,7 +1689,7 @@ fi if test "${enable_shared+set}" = set; then enableval="$enable_shared" p=${PACKAGE-default} -case "$enableval" in +case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) @@ -1723,7 +1712,7 @@ fi if test "${enable_static+set}" = set; then enableval="$enable_static" p=${PACKAGE-default} -case "$enableval" in +case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) @@ -1746,7 +1735,7 @@ fi if test "${enable_fast_install+set}" = set; then enableval="$enable_fast_install" p=${PACKAGE-default} -case "$enableval" in +case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) @@ -1774,10 +1763,10 @@ else fi ac_prog=ld -if test "$ac_cv_prog_gcc" = yes; then +if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 -echo "configure:1781: checking for ld used by GCC" >&5 +echo "configure:1770: checking for ld used by GCC" >&5 case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw @@ -1785,7 +1774,7 @@ echo "configure:1781: checking for ld used by GCC" >&5 *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac - case "$ac_prog" in + case $ac_prog in # Accept absolute paths. [\\/]* | [A-Za-z]:[\\/]*) re_direlt='/[^/][^/]*/\.\./' @@ -1807,12 +1796,12 @@ echo "configure:1781: checking for ld used by GCC" >&5 esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:1811: checking for GNU ld" >&5 +echo "configure:1800: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:1814: checking for non-GNU ld" >&5 +echo "configure:1803: checking for non-GNU ld" >&5 fi -if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then +if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -z "$LD"; then @@ -1820,11 +1809,11 @@ else for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - ac_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. - if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then test "$with_gnu_ld" != no && break else test "$with_gnu_ld" != yes && break @@ -1833,11 +1822,11 @@ else done IFS="$ac_save_ifs" else - ac_cv_path_LD="$LD" # Let the user override the test with a path. + lt_cv_path_LD="$LD" # Let the user override the test with a path. fi fi -LD="$ac_cv_path_LD" +LD="$lt_cv_path_LD" if test -n "$LD"; then echo "$ac_t""$LD" 1>&6 else @@ -1845,24 +1834,24 @@ else fi test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:1849: checking if the linker ($LD) is GNU ld" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then +echo "configure:1838: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LD -v 2>&1 &5; then - ac_cv_prog_gnu_ld=yes + lt_cv_prog_gnu_ld=yes else - ac_cv_prog_gnu_ld=no + lt_cv_prog_gnu_ld=no fi fi -echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 -with_gnu_ld=$ac_cv_prog_gnu_ld +echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6 +with_gnu_ld=$lt_cv_prog_gnu_ld echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 -echo "configure:1866: checking for $LD option to reload object files" >&5 +echo "configure:1855: checking for $LD option to reload object files" >&5 if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1874,13 +1863,13 @@ reload_flag=$lt_cv_ld_reload_flag test -n "$reload_flag" && reload_flag=" $reload_flag" echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 -echo "configure:1878: checking for BSD-compatible nm" >&5 -if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then +echo "configure:1867: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$NM"; then # Let the user override the test. - ac_cv_path_NM="$NM" + lt_cv_path_NM="$NM" else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do @@ -1892,27 +1881,27 @@ else # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then - ac_cv_path_NM="$tmp_nm -B" + lt_cv_path_NM="$tmp_nm -B" break elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - ac_cv_path_NM="$tmp_nm -p" + lt_cv_path_NM="$tmp_nm -p" break else - ac_cv_path_NM=${ac_cv_path_NM="$tmp_nm"} # keep the first match, but + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags fi fi done IFS="$ac_save_ifs" - test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi fi -NM="$ac_cv_path_NM" +NM="$lt_cv_path_NM" echo "$ac_t""$NM" 1>&6 echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6 -echo "configure:1916: checking how to recognise dependant libraries" >&5 +echo "configure:1905: checking how to recognise dependant libraries" >&5 if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1930,8 +1919,8 @@ lt_cv_deplibs_check_method='unknown' # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. -case "$host_os" in -aix4*) +case $host_os in +aix*) lt_cv_deplibs_check_method=pass_all ;; @@ -1940,8 +1929,8 @@ beos*) ;; bsdi4*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -1950,14 +1939,20 @@ cygwin* | mingw* |pw32*) lt_cv_file_magic_cmd='$OBJDUMP -f' ;; +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + freebsd* ) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case "$host_cpu" in + case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -1970,29 +1965,28 @@ gnu*) lt_cv_deplibs_check_method=pass_all ;; -hpux10.20*) - # TODO: Does this work for hpux-11 too? - lt_cv_deplibs_check_method='file_magic (s0-90-90-9|PA-RISC0-9.0-9) shared library' +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; irix5* | irix6*) - case "$host_os" in + case $host_os in irix5*) # this will be overridden with pass_all, but let us keep it just in case lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" ;; *) - case "$LD" in + case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" - ;; + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; esac lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` lt_cv_deplibs_check_method=pass_all @@ -2000,23 +1994,30 @@ irix5* | irix6*) # This must be Linux ELF. linux-gnu*) - case "$host_cpu" in + case $host_cpu in alpha* | i*86 | powerpc* | sparc* | ia64* ) lt_cv_deplibs_check_method=pass_all ;; *) # glibc up to 2.1.1 does not perform some relocations on ARM - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; - esac + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` ;; netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then : + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='file_magic NetBSD/[a-z0-9]* demand paged shared library' else - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' fi + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + +newsos6) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; osf3* | osf4* | osf5*) @@ -2036,13 +2037,13 @@ solaris*) ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case "$host_vendor" in + case $host_vendor in ncr) lt_cv_deplibs_check_method=pass_all ;; motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; esac ;; @@ -2055,13 +2056,13 @@ file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method echo $ac_n "checking for object suffix""... $ac_c" 1>&6 -echo "configure:2059: checking for object suffix" >&5 +echo "configure:2060: checking for object suffix" >&5 if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftest* echo 'int i = 1;' > conftest.$ac_ext -if { (eval echo configure:2065: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2066: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then for ac_file in conftest.*; do case $ac_file in *.c) ;; @@ -2081,15 +2082,15 @@ ac_objext=$ac_cv_objext # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! # Only perform the check for file, if the check method requires it -case "$deplibs_check_method" in +case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 -echo "configure:2089: checking for ${ac_tool_prefix}file" >&5 +echo "configure:2090: checking for ${ac_tool_prefix}file" >&5 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - case "$MAGIC_CMD" in + case $MAGIC_CMD in /*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; @@ -2105,7 +2106,7 @@ else if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then - case "$deplibs_check_method" in + case $deplibs_check_method in "file_magic "*) file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" MAGIC_CMD="$lt_cv_path_MAGIC_CMD" @@ -2147,11 +2148,11 @@ fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then echo $ac_n "checking for file""... $ac_c" 1>&6 -echo "configure:2151: checking for file" >&5 +echo "configure:2152: checking for file" >&5 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - case "$MAGIC_CMD" in + case $MAGIC_CMD in /*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; @@ -2167,7 +2168,7 @@ else if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then - case "$deplibs_check_method" in + case $deplibs_check_method in "file_magic "*) file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" MAGIC_CMD="$lt_cv_path_MAGIC_CMD" @@ -2218,7 +2219,7 @@ esac # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2222: checking for $ac_word" >&5 +echo "configure:2223: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2250,7 +2251,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2254: checking for $ac_word" >&5 +echo "configure:2255: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2285,7 +2286,7 @@ fi # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2289: checking for $ac_word" >&5 +echo "configure:2290: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2317,7 +2318,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2321: checking for $ac_word" >&5 +echo "configure:2322: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2355,8 +2356,8 @@ libtool_flags="--cache-file=$cache_file" test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" -test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" -test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" libtool_flags="$libtool_flags --enable-dlopen" # Check whether --enable-libtool-lock or --disable-libtool-lock was given. @@ -2381,12 +2382,12 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" # Some flags need to be propagated to the compiler or linker for good # libtool support. -case "$host" in +case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 2388 "configure"' > conftest.$ac_ext - if { (eval echo configure:2389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - case "`/usr/bin/file conftest.o`" in + echo '#line 2389 "configure"' > conftest.$ac_ext + if { (eval echo configure:2390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -2406,7 +2407,7 @@ case "$host" in SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 -echo "configure:2410: checking whether the C compiler needs -belf" >&5 +echo "configure:2411: checking whether the C compiler needs -belf" >&5 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2419,14 +2420,14 @@ ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$a cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* lt_cv_cc_needs_belf=yes else @@ -2456,7 +2457,7 @@ echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 esac echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 -echo "configure:2460: checking how to run the C++ preprocessor" >&5 +echo "configure:2461: checking how to run the C++ preprocessor" >&5 if test -z "$CXXCPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2469,12 +2470,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross CXXCPP="${CXX-g++} -E" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2478: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2479: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2581,12 +2582,11 @@ exec 5>>./config.log - LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh" lt_save_CC="$CC" lt_save_CFLAGS="$CFLAGS" AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ -MAGIC_CMD="$MAGIC_CMD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ @@ -2602,7 +2602,6 @@ CFLAGS="$lt_save_CFLAGS" # clobbered by the next message. exec 5>>./config.log - @@ -2692,38 +2691,77 @@ EOF fi -EXCEPTIONSPEC= +echo $ac_n "checking for exception model to use""... $ac_c" 1>&6 +echo "configure:2696: checking for exception model to use" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + # Check whether --enable-sjlj-exceptions or --disable-sjlj-exceptions was given. if test "${enable_sjlj_exceptions+set}" = set; then enableval="$enable_sjlj_exceptions" - if test "$enable_sjlj_exceptions" = yes; then - # This can be set in configure.host. - libgcj_sjlj=yes + : +else + cat > conftest.$ac_ext << EOF +#line 2711 "configure" +struct S { ~S(); }; +void bar(); +void foo() +{ + S s; + bar(); +} +EOF +old_CXXFLAGS="$CXXFLAGS" +CXXFLAGS=-S +if { (eval echo configure:2722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes + elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no fi fi +CXXFLAGS="$old_CXXFLAGS" +rm -f conftest* +fi - -if test "$libgcj_sjlj" = yes; then - EXCEPTIONSPEC="-fsjlj-exceptions" - cat >> confdefs.h <<\EOF +if test x$enable_sjlj_exceptions = xyes; then + cat >> confdefs.h <<\EOF #define SJLJ_EXCEPTIONS 1 EOF + ac_exception_model_name=sjlj +elif test x$enable_sjlj_exceptions = xno; then + ac_exception_model_name="call frame" +else + { echo "configure: error: unable to detect exception model" 1>&2; exit 1; } fi +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_exception_model_name" 1>&6 echo $ac_n "checking for data_start""... $ac_c" 1>&6 -echo "configure:2716: checking for data_start" >&5 +echo "configure:2754: checking for data_start" >&5 LIBDATASTARTSPEC= NEEDS_DATA_START= cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""found it" 1>&6 else @@ -2793,7 +2831,7 @@ EOF esac echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:2797: checking how to run the C preprocessor" >&5 +echo "configure:2835: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -2808,13 +2846,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2818: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2856: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2825,13 +2863,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2835: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2873: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2842,13 +2880,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2852: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2890: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2873,7 +2911,7 @@ fi echo "$ac_t""$CPP" 1>&6 cat > conftest.$ac_ext < EOF @@ -2888,7 +2926,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2903,7 +2941,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2918,7 +2956,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2935,7 +2973,7 @@ rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2950,7 +2988,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2994,7 +3032,7 @@ ZLIBTESTSPEC= libsubdir=.libs echo $ac_n "checking for garbage collector to use""... $ac_c" 1>&6 -echo "configure:2998: checking for garbage collector to use" >&5 +echo "configure:3036: checking for garbage collector to use" >&5 # Check whether --enable-java-gc or --disable-java-gc was given. if test "${enable_java_gc+set}" = set; then enableval="$enable_java_gc" @@ -3050,7 +3088,7 @@ esac echo $ac_n "checking for threads package to use""... $ac_c" 1>&6 -echo "configure:3054: checking for threads package to use" >&5 +echo "configure:3092: checking for threads package to use" >&5 # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" @@ -3173,16 +3211,17 @@ CANADIAN=no NULL_TARGET=no NATIVE=yes -# Find eh-common.h and support headers. If we're in the tree with +# Find unwind.h and support headers. If we're in the tree with # gcc, then look there. Otherwise look in compat-include. If all else # fails, just hope the user has set things up somehow. -if test -r $srcdir/../gcc/eh-common.h; then - EH_COMMON_INCLUDE='-I$(top_srcdir)/../gcc -I$(top_srcdir)/../include' +echo "probing $srcdir/../gcc/unwind.h" +if test -r $srcdir/../gcc/unwind.h; then + GCC_UNWIND_INCLUDE='-I$(top_srcdir)/../gcc' else if test -d $srcdir/../compat-include; then - EH_COMMON_INCLUDE='-I$(top_srcdir)/../compat-include' + GCC_UNWIND_INCLUDE='-I$(top_srcdir)/../compat-include' else - EH_COMMON_INCLUDE= + GCC_UNWIND_INCLUDE= fi fi @@ -3234,7 +3273,7 @@ EOF # directory. if test "$build" != "$with_cross_host"; then CANADIAN=yes - EH_COMMON_INCLUDE= + GCC_UNWIND_INCLUDE= GCJ="${target_alias}-gcj" else GCJ= @@ -3244,12 +3283,12 @@ else for ac_func in strerror ioctl select fstat open fsync sleep do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3248: checking for $ac_func" >&5 +echo "configure:3287: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3299,12 +3338,12 @@ done for ac_func in gmtime_r localtime_r readdir_r getpwuid_r getcwd do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3303: checking for $ac_func" >&5 +echo "configure:3342: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3354,12 +3393,12 @@ done for ac_func in access stat mkdir rename rmdir unlink realpath do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3358: checking for $ac_func" >&5 +echo "configure:3397: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3409,12 +3448,12 @@ done for ac_func in iconv nl_langinfo setlocale do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3413: checking for $ac_func" >&5 +echo "configure:3452: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3464,12 +3503,12 @@ done for ac_func in inet_aton inet_addr do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3468: checking for $ac_func" >&5 +echo "configure:3507: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3519,12 +3558,12 @@ done for ac_func in inet_pton uname inet_ntoa do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3523: checking for $ac_func" >&5 +echo "configure:3562: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3574,12 +3613,12 @@ done for ac_func in backtrace fork execvp pipe do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3578: checking for $ac_func" >&5 +echo "configure:3617: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3630,17 +3669,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3634: checking for $ac_hdr" >&5 +echo "configure:3673: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3644: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3683: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3667,7 +3706,7 @@ fi done echo $ac_n "checking for dladdr in -ldl""... $ac_c" 1>&6 -echo "configure:3671: checking for dladdr in -ldl" >&5 +echo "configure:3710: checking for dladdr in -ldl" >&5 ac_lib_var=`echo dl'_'dladdr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3675,7 +3714,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3715,7 +3754,7 @@ do ac_safe=`echo "$ac_file" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_file""... $ac_c" 1>&6 -echo "configure:3719: checking for $ac_file" >&5 +echo "configure:3758: checking for $ac_file" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3750,12 +3789,12 @@ done for ac_func in gethostbyname_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3754: checking for $ac_func" >&5 +echo "configure:3793: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3805,7 +3844,7 @@ EOF # We look for the one that returns `int'. # Hopefully this check is robust enough. cat > conftest.$ac_ext < EOF @@ -3825,7 +3864,7 @@ rm -f conftest* *" -D_REENTRANT "*) ;; *) echo $ac_n "checking whether gethostbyname_r declaration requires -D_REENTRANT""... $ac_c" 1>&6 -echo "configure:3829: checking whether gethostbyname_r declaration requires -D_REENTRANT" >&5 +echo "configure:3868: checking whether gethostbyname_r declaration requires -D_REENTRANT" >&5 if eval "test \"`echo '$''{'libjava_cv_gethostbyname_r_needs_reentrant'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3838,14 +3877,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { gethostbyname_r("", 0, 0); ; return 0; } EOF -if { (eval echo configure:3849: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3888: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* libjava_cv_gethostbyname_r_needs_reentrant=no else @@ -3855,14 +3894,14 @@ else CPPFLAGS_SAVE="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -D_REENTRANT" cat > conftest.$ac_ext < int main() { gethostbyname_r("", 0, 0); ; return 0; } EOF -if { (eval echo configure:3866: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3905: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* libjava_cv_gethostbyname_r_needs_reentrant=yes else @@ -3897,12 +3936,12 @@ EOF esac echo $ac_n "checking for struct hostent_data""... $ac_c" 1>&6 -echo "configure:3901: checking for struct hostent_data" >&5 +echo "configure:3940: checking for struct hostent_data" >&5 if eval "test \"`echo '$''{'libjava_cv_struct_hostent_data'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3956: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* libjava_cv_struct_hostent_data=yes else @@ -3942,12 +3981,12 @@ done for ac_func in gethostbyaddr_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3946: checking for $ac_func" >&5 +echo "configure:3985: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3997,7 +4036,7 @@ EOF # We look for the one that returns `int'. # Hopefully this check is robust enough. cat > conftest.$ac_ext < EOF @@ -4021,12 +4060,12 @@ done for ac_func in gethostname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4025: checking for $ac_func" >&5 +echo "configure:4064: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4073,7 +4112,7 @@ EOF EOF cat > conftest.$ac_ext < EOF @@ -4104,12 +4143,12 @@ done for ac_func in pthread_mutexattr_settype pthread_mutexattr_setkind_np do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4108: checking for $ac_func" >&5 +echo "configure:4147: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4162,12 +4201,12 @@ done for ac_func in sched_yield do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4166: checking for $ac_func" >&5 +echo "configure:4205: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4212,7 +4251,7 @@ EOF else echo "$ac_t""no" 1>&6 echo $ac_n "checking for sched_yield in -lrt""... $ac_c" 1>&6 -echo "configure:4216: checking for sched_yield in -lrt" >&5 +echo "configure:4255: checking for sched_yield in -lrt" >&5 ac_lib_var=`echo rt'_'sched_yield | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4220,7 +4259,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lrt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4257,7 +4296,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for sched_yield in -lposix4""... $ac_c" 1>&6 -echo "configure:4261: checking for sched_yield in -lposix4" >&5 +echo "configure:4300: checking for sched_yield in -lposix4" >&5 ac_lib_var=`echo posix4'_'sched_yield | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4265,7 +4304,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lposix4 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4312,7 +4351,7 @@ done # We can save a little space at runtime if the mutex has m_count # or __m_count. This is a nice hack for Linux. cat > conftest.$ac_ext < int main() { @@ -4321,7 +4360,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:4325: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define PTHREAD_MUTEX_HAVE_M_COUNT 1 @@ -4333,7 +4372,7 @@ else rm -rf conftest* cat > conftest.$ac_ext < int main() { @@ -4342,7 +4381,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:4346: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4385: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define PTHREAD_MUTEX_HAVE___M_COUNT 1 @@ -4362,12 +4401,12 @@ rm -f conftest* for ac_func in gettimeofday time ftime do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4366: checking for $ac_func" >&5 +echo "configure:4405: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4421,12 +4460,12 @@ done for ac_func in memmove do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4425: checking for $ac_func" >&5 +echo "configure:4464: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4479,12 +4518,12 @@ done for ac_func in memcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4483: checking for $ac_func" >&5 +echo "configure:4522: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4555,7 +4594,7 @@ done #-------------------------------------------------------------------- echo $ac_n "checking for socket libraries""... $ac_c" 1>&6 -echo "configure:4559: checking for socket libraries" >&5 +echo "configure:4598: checking for socket libraries" >&5 if eval "test \"`echo '$''{'gcj_cv_lib_sockets'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4563,12 +4602,12 @@ else gcj_checkBoth=0 unset ac_cv_func_connect echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:4567: checking for connect" >&5 +echo "configure:4606: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else @@ -4614,7 +4653,7 @@ fi if test "$gcj_checkSocket" = 1; then unset ac_cv_func_connect echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 -echo "configure:4618: checking for main in -lsocket" >&5 +echo "configure:4657: checking for main in -lsocket" >&5 ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4622,14 +4661,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4656,12 +4695,12 @@ fi LIBS="$LIBS -lsocket -lnsl" unset ac_cv_func_accept echo $ac_n "checking for accept""... $ac_c" 1>&6 -echo "configure:4660: checking for accept" >&5 +echo "configure:4699: checking for accept" >&5 if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_accept=yes" else @@ -4711,12 +4750,12 @@ fi gcj_oldLibs=$LIBS LIBS="$LIBS $gcj_cv_lib_sockets" echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:4715: checking for gethostbyname" >&5 +echo "configure:4754: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else @@ -4757,7 +4796,7 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6 -echo "configure:4761: checking for main in -lnsl" >&5 +echo "configure:4800: checking for main in -lnsl" >&5 ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4765,14 +4804,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4815: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4804,7 +4843,7 @@ echo "$ac_t""$gcj_cv_lib_sockets" 1>&6 if test "$with_system_zlib" = yes; then echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 -echo "configure:4808: checking for deflate in -lz" >&5 +echo "configure:4847: checking for deflate in -lz" >&5 ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4812,7 +4851,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lz $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4853,7 +4892,7 @@ fi # requires -ldl. if test "$GC" = boehm; then echo $ac_n "checking for main in -ldl""... $ac_c" 1>&6 -echo "configure:4857: checking for main in -ldl" >&5 +echo "configure:4896: checking for main in -ldl" >&5 ac_lib_var=`echo dl'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4861,14 +4900,14 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4910,11 +4949,10 @@ fi # Create it, so that compile/link tests don't fail test -f libgcj.spec || touch libgcj.spec - - # Extract the first word of "${ac_tool_prefix}gcj", so it can be a program name with args. +# Extract the first word of "${ac_tool_prefix}gcj", so it can be a program name with args. set dummy ${ac_tool_prefix}gcj; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4918: checking for $ac_word" >&5 +echo "configure:4956: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_GCJ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4946,7 +4984,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "gcj", so it can be a program name with args. set dummy gcj; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4950: checking for $ac_word" >&5 +echo "configure:4988: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_GCJ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4986,7 +5024,7 @@ LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh" lt_save_CC="$CC" lt_save_CFLAGS="$CFLAGS" AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \ -MAGIC_CMD="$MAGIC_CMD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ @@ -5006,7 +5044,7 @@ exec 5>>./config.log echo $ac_n "checking size of void *""... $ac_c" 1>&6 -echo "configure:5010: checking size of void *" >&5 +echo "configure:5048: checking size of void *" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5014,7 +5052,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -5025,7 +5063,7 @@ main() exit(0); } EOF -if { (eval echo configure:5029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_void_p=`cat conftestval` else @@ -5064,7 +5102,6 @@ fi - if test "$CANADIAN" = yes; then CANADIAN_TRUE= CANADIAN_FALSE='#' @@ -5122,18 +5159,18 @@ EOF echo $ac_n "checking for g++ -ffloat-store bug""... $ac_c" 1>&6 -echo "configure:5126: checking for g++ -ffloat-store bug" >&5 +echo "configure:5163: checking for g++ -ffloat-store bug" >&5 save_CFLAGS="$CFLAGS" CFLAGS="-x c++ -O2 -ffloat-store" cat > conftest.$ac_ext < int main() { ; return 0; } EOF -if { (eval echo configure:5137: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5174: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""no" 1>&6 else @@ -5153,17 +5190,17 @@ for ac_hdr in unistd.h bstring.h sys/time.h sys/types.h fcntl.h sys/ioctl.h sys/ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5157: checking for $ac_hdr" >&5 +echo "configure:5194: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5167: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5193,17 +5230,17 @@ for ac_hdr in dirent.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5197: checking for $ac_hdr" >&5 +echo "configure:5234: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5207: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5244: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5231,12 +5268,12 @@ done echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:5235: checking for ANSI C header files" >&5 +echo "configure:5272: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5244,7 +5281,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5248: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5261,7 +5298,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -5279,7 +5316,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -5300,7 +5337,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -5311,7 +5348,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:5315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -5335,12 +5372,12 @@ EOF fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:5339: checking for ssize_t" >&5 +echo "configure:5376: checking for ssize_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5369,9 +5406,9 @@ fi echo $ac_n "checking for in_addr_t""... $ac_c" 1>&6 -echo "configure:5373: checking for in_addr_t" >&5 +echo "configure:5410: checking for in_addr_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5385,7 +5422,7 @@ int main() { in_addr_t foo; ; return 0; } EOF -if { (eval echo configure:5389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_IN_ADDR_T 1 @@ -5401,16 +5438,16 @@ fi rm -f conftest* echo $ac_n "checking whether struct ip_mreq is in netinet/in.h""... $ac_c" 1>&6 -echo "configure:5405: checking whether struct ip_mreq is in netinet/in.h" >&5 +echo "configure:5442: checking whether struct ip_mreq is in netinet/in.h" >&5 cat > conftest.$ac_ext < int main() { struct ip_mreq mreq; ; return 0; } EOF -if { (eval echo configure:5414: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5451: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_STRUCT_IP_MREQ 1 @@ -5426,16 +5463,16 @@ fi rm -f conftest* echo $ac_n "checking whether struct sockaddr_in6 is in netinet/in.h""... $ac_c" 1>&6 -echo "configure:5430: checking whether struct sockaddr_in6 is in netinet/in.h" >&5 +echo "configure:5467: checking whether struct sockaddr_in6 is in netinet/in.h" >&5 cat > conftest.$ac_ext < int main() { struct sockaddr_in6 addr6; ; return 0; } EOF -if { (eval echo configure:5439: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5476: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_INET6 1 @@ -5451,9 +5488,9 @@ fi rm -f conftest* echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6 -echo "configure:5455: checking for socklen_t in sys/socket.h" >&5 +echo "configure:5492: checking for socklen_t in sys/socket.h" >&5 cat > conftest.$ac_ext < #include @@ -5461,7 +5498,7 @@ int main() { socklen_t x = 5; ; return 0; } EOF -if { (eval echo configure:5465: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5502: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_SOCKLEN_T 1 @@ -5477,16 +5514,16 @@ fi rm -f conftest* echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6 -echo "configure:5481: checking for tm_gmtoff in struct tm" >&5 +echo "configure:5518: checking for tm_gmtoff in struct tm" >&5 cat > conftest.$ac_ext < int main() { struct tm tim; tim.tm_gmtoff = 0; ; return 0; } EOF -if { (eval echo configure:5490: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5527: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define STRUCT_TM_HAS_GMTOFF 1 @@ -5499,16 +5536,16 @@ else rm -rf conftest* echo "$ac_t""no" 1>&6 echo $ac_n "checking for global timezone variable""... $ac_c" 1>&6 -echo "configure:5503: checking for global timezone variable" >&5 +echo "configure:5540: checking for global timezone variable" >&5 cat > conftest.$ac_ext < int main() { long z2 = timezone; ; return 0; } EOF -if { (eval echo configure:5512: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5549: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_TIMEZONE 1 @@ -5528,19 +5565,19 @@ rm -f conftest* # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:5532: checking for working alloca.h" >&5 +echo "configure:5569: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:5544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -5561,12 +5598,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:5565: checking for alloca" >&5 +echo "configure:5602: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -5626,12 +5663,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:5630: checking whether alloca needs Cray hooks" >&5 +echo "configure:5667: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5660: checking for $ac_func" >&5 +echo "configure:5697: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5725: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5711,7 +5748,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:5715: checking stack direction for C alloca" >&5 +echo "configure:5752: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5719,7 +5756,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -5765,7 +5802,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5769: checking for $ac_word" >&5 +echo "configure:5806: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5834,7 +5871,7 @@ fi # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:5838: checking for X" >&5 +echo "configure:5875: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -5896,12 +5933,12 @@ if test "$ac_x_includes" = NO; then # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5905: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5942: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5970,14 +6007,14 @@ if test "$ac_x_libraries" = NO; then ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -6083,17 +6120,17 @@ else case "`(uname -sr) 2>/dev/null`" in "SunOS 5"*) echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 -echo "configure:6087: checking whether -R must be followed by a space" >&5 +echo "configure:6124: checking whether -R must be followed by a space" >&5 ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_nospace=yes else @@ -6109,14 +6146,14 @@ rm -f conftest* else LIBS="$ac_xsave_LIBS -R $x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_space=yes else @@ -6148,7 +6185,7 @@ rm -f conftest* # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 -echo "configure:6152: checking for dnet_ntoa in -ldnet" >&5 +echo "configure:6189: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6156,7 +6193,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6189,7 +6226,7 @@ fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:6193: checking for dnet_ntoa in -ldnet_stub" >&5 +echo "configure:6230: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6197,7 +6234,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6237,12 +6274,12 @@ fi # The nsl library prevents programs from opening the X display # on Irix 5.2, according to dickey@clark.net. echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:6241: checking for gethostbyname" >&5 +echo "configure:6278: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else @@ -6286,7 +6323,7 @@ fi if test $ac_cv_func_gethostbyname = no; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 -echo "configure:6290: checking for gethostbyname in -lnsl" >&5 +echo "configure:6327: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6294,7 +6331,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6346: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6335,12 +6372,12 @@ fi # -lsocket must be given before -lnsl if both are needed. # We assume that if connect needs -lnsl, so does gethostbyname. echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:6339: checking for connect" >&5 +echo "configure:6376: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else @@ -6384,7 +6421,7 @@ fi if test $ac_cv_func_connect = no; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 -echo "configure:6388: checking for connect in -lsocket" >&5 +echo "configure:6425: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6392,7 +6429,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6427,12 +6464,12 @@ fi # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. echo $ac_n "checking for remove""... $ac_c" 1>&6 -echo "configure:6431: checking for remove" >&5 +echo "configure:6468: checking for remove" >&5 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_remove=yes" else @@ -6476,7 +6513,7 @@ fi if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 -echo "configure:6480: checking for remove in -lposix" >&5 +echo "configure:6517: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6484,7 +6521,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6519,12 +6556,12 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. echo $ac_n "checking for shmat""... $ac_c" 1>&6 -echo "configure:6523: checking for shmat" >&5 +echo "configure:6560: checking for shmat" >&5 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else @@ -6568,7 +6605,7 @@ fi if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 -echo "configure:6572: checking for shmat in -lipc" >&5 +echo "configure:6609: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6576,7 +6613,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lipc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6620,7 +6657,7 @@ fi # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 -echo "configure:6624: checking for IceConnectionNumber in -lICE" >&5 +echo "configure:6661: checking for IceConnectionNumber in -lICE" >&5 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6628,7 +6665,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6931,7 +6968,6 @@ s%@ZLIBS@%$ZLIBS%g s%@ZDEPS@%$ZDEPS%g s%@ZINCS@%$ZINCS%g s%@DIVIDESPEC@%$DIVIDESPEC%g -s%@EXCEPTIONSPEC@%$EXCEPTIONSPEC%g s%@CANADIAN_TRUE@%$CANADIAN_TRUE%g s%@CANADIAN_FALSE@%$CANADIAN_FALSE%g s%@NULL_TARGET_TRUE@%$NULL_TARGET_TRUE%g @@ -6942,7 +6978,7 @@ s%@USE_LIBDIR_TRUE@%$USE_LIBDIR_TRUE%g s%@USE_LIBDIR_FALSE@%$USE_LIBDIR_FALSE%g s%@NEEDS_DATA_START_TRUE@%$NEEDS_DATA_START_TRUE%g s%@NEEDS_DATA_START_FALSE@%$NEEDS_DATA_START_FALSE%g -s%@EH_COMMON_INCLUDE@%$EH_COMMON_INCLUDE%g +s%@GCC_UNWIND_INCLUDE@%$GCC_UNWIND_INCLUDE%g s%@AM_RUNTESTFLAGS@%$AM_RUNTESTFLAGS%g s%@ALLOCA@%$ALLOCA%g s%@PERL@%$PERL%g diff --git a/libjava/configure.host b/libjava/configure.host index e466b63c971..077825c88d0 100644 --- a/libjava/configure.host +++ b/libjava/configure.host @@ -23,7 +23,6 @@ libgcj_flags= libgcj_cflags= libgcj_cxxflags= libgcj_javaflags= -libgcj_sjlj= libgcj_interpreter= case "${target_optspace}:${host}" in @@ -67,18 +66,13 @@ case "${host}" in alpha*-*) libgcj_flags="${libgcj_flags} -mieee" libgcj_interpreter=yes - libgcj_sjlj=yes ;; sparc-*) ;; ia64-*) libgcj_flags="${libgcj_flags} -funwind-tables" - libgcj_sjlj=yes libgcj_interpreter=yes ;; - *) - libgcj_sjlj=yes - ;; esac libgcj_cflags="${libgcj_cflags} ${libgcj_flags}" diff --git a/libjava/configure.in b/libjava/configure.in index aa5d8ab32da..89bbe7fb198 100644 --- a/libjava/configure.in +++ b/libjava/configure.in @@ -88,19 +88,51 @@ if test "$libgcj_interpreter" = yes; then AC_DEFINE(INTERPRETER) fi -EXCEPTIONSPEC= -dnl See if we should use setjmp/longjmp exceptions +AC_MSG_CHECKING([for exception model to use]) +AC_LANG_SAVE +AC_LANG_CPLUSPLUS AC_ARG_ENABLE(sjlj-exceptions, -[ --enable-sjlj-exceptions use setjmp/longjmp exceptions], - if test "$enable_sjlj_exceptions" = yes; then - # This can be set in configure.host. - libgcj_sjlj=yes - fi) - -if test "$libgcj_sjlj" = yes; then - EXCEPTIONSPEC="-fsjlj-exceptions" - AC_DEFINE(SJLJ_EXCEPTIONS) +[ --enable-sjlj-exceptions force use of builtin_setjmp for exceptions], +[:], +[dnl Botheration. Now we've got to detect the exception model. +dnl Link tests against libgcc.a are problematic since -- at least +dnl as of this writing -- we've not been given proper -L bits for +dnl single-tree newlib and libgloss. +dnl +dnl This is what AC_TRY_COMPILE would do if it didn't delete the +dnl conftest files before we got a change to grep them first. +cat > conftest.$ac_ext << EOF +[#]line __oline__ "configure" +struct S { ~S(); }; +void bar(); +void foo() +{ + S s; + bar(); +} +EOF +old_CXXFLAGS="$CXXFLAGS" +CXXFLAGS=-S +if AC_TRY_EVAL(ac_compile); then + if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes + elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no + fi +fi +CXXFLAGS="$old_CXXFLAGS" +rm -f conftest*]) +if test x$enable_sjlj_exceptions = xyes; then + AC_DEFINE(SJLJ_EXCEPTIONS, 1, + [Define if the compiler is configured for setjmp/longjmp exceptions.]) + ac_exception_model_name=sjlj +elif test x$enable_sjlj_exceptions = xno; then + ac_exception_model_name="call frame" +else + AC_MSG_ERROR([unable to detect exception model]) fi +AC_LANG_RESTORE +AC_MSG_RESULT($ac_exception_model_name) AC_MSG_CHECKING([for data_start]) LIBDATASTARTSPEC= @@ -349,16 +381,17 @@ CANADIAN=no NULL_TARGET=no NATIVE=yes -# Find eh-common.h and support headers. If we're in the tree with +# Find unwind.h and support headers. If we're in the tree with # gcc, then look there. Otherwise look in compat-include. If all else # fails, just hope the user has set things up somehow. -if test -r $srcdir/../gcc/eh-common.h; then - EH_COMMON_INCLUDE='-I$(top_srcdir)/../gcc -I$(top_srcdir)/../include' +echo "probing $srcdir/../gcc/unwind.h" +if test -r $srcdir/../gcc/unwind.h; then + GCC_UNWIND_INCLUDE='-I$(top_srcdir)/../gcc' else if test -d $srcdir/../compat-include; then - EH_COMMON_INCLUDE='-I$(top_srcdir)/../compat-include' + GCC_UNWIND_INCLUDE='-I$(top_srcdir)/../compat-include' else - EH_COMMON_INCLUDE= + GCC_UNWIND_INCLUDE= fi fi @@ -389,7 +422,7 @@ if test -n "${with_cross_host}"; then # directory. if test "$build" != "$with_cross_host"; then CANADIAN=yes - EH_COMMON_INCLUDE= + GCC_UNWIND_INCLUDE= GCJ="${target_alias}-gcj" else GCJ= @@ -623,14 +656,13 @@ AC_SUBST(ZLIBS) AC_SUBST(ZDEPS) AC_SUBST(ZINCS) AC_SUBST(DIVIDESPEC) -AC_SUBST(EXCEPTIONSPEC) AM_CONDITIONAL(CANADIAN, test "$CANADIAN" = yes) AM_CONDITIONAL(NULL_TARGET, test "$NULL_TARGET" = yes) AM_CONDITIONAL(NATIVE, test "$NATIVE" = yes || test "$NULL_TARGET" = yes) AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host") AM_CONDITIONAL(NEEDS_DATA_START, test "$NEEDS_DATA_START" = yes && test "$NATIVE" = yes) -AC_SUBST(EH_COMMON_INCLUDE) +AC_SUBST(GCC_UNWIND_INCLUDE) # Determine gcj version number. changequote(<<,>>) diff --git a/libjava/exception.cc b/libjava/exception.cc index fdbfc420c0e..41f7676063e 100644 --- a/libjava/exception.cc +++ b/libjava/exception.cc @@ -1,6 +1,6 @@ // Functions for Exception Support for Java. -/* Copyright (C) 1998, 1999 Free Software Foundation +/* Copyright (C) 1998, 1999, 2001 Free Software Foundation This file is part of libgcj. @@ -18,182 +18,546 @@ details. */ #include #include -// eh-common.h needs gansidecl.h. -#include "gansidecl.h" -#include "eh-common.h" - -typedef struct { - __eh_info eh_info; - jthrowable value; -} java_eh_info; +#include "unwind.h" + +// More nastiness: the GC wants to define TRUE and FALSE. We don't +// need the Java definitions (themselves a hack), so we undefine them. +#undef TRUE +#undef FALSE -/* Language-specific EH info pointer, throw routine, and language/version - info routines. All defined in libgcc2. */ +extern "C" +{ +#include +#include +#include +}; -extern "C" java_eh_info **__get_eh_info (); -extern "C" void __throw () __attribute__ ((__noreturn__)); -extern "C" void __sjthrow () __attribute__ ((__noreturn__)); -extern "C" short __get_eh_table_version (void *table); -extern "C" short __get_eh_table_language (void *table); -extern "C" void *__get_eh_context (); + +struct alignment_test_struct +{ + char space; + char end[0] __attribute__((aligned)); +}; -extern "C" void * -_Jv_type_matcher (java_eh_info *info, void* match_info, - void *exception_table) +struct java_exception_header { -#ifndef SJLJ_EXCEPTIONS - /* No exception table implies the old style mechanism, so don't check. */ - if (exception_table != NULL - && __get_eh_table_language (exception_table) != EH_LANG_Java) - return NULL; -#endif + /* Cache handler details between Phase 1 and Phase 2. */ + _Unwind_Ptr landingPad; + int handlerSwitchValue; - /* we don't worry about version info yet, there is only one version! */ - - if (match_info != NULL) - { - // The match_info is either a (java::lang::Class*) or - // match_info is one more than a (Utf8Const*). - if (sizeof(void*) != sizeof(size_t)) - abort(); - size_t mi = (size_t) match_info; - if ((mi & 1) != 0) - match_info = _Jv_FindClass ((Utf8Const*) (mi - 1), NULL); - if (! _Jv_IsInstanceOf (info->value, (jclass) match_info)) - return NULL; - } + /* The object being thrown. Compiled code expects this to be immediately + before the generic exception header. Which is complicated by the fact + that _Unwind_Exception is ((aligned)). */ + + char pad[sizeof(jthrowable) < sizeof(alignment_test_struct) + ? sizeof(alignment_test_struct) - sizeof(jthrowable) : 0] + __attribute__((aligned)); + + jthrowable value; - return info->value; + /* The generic exception header. */ + _Unwind_Exception unwindHeader; +}; + +// This is the exception class we report -- "GNUCJAVA". +const _Unwind_Exception_Class __gcj_exception_class += ((((((((_Unwind_Exception_Class) 'G' + << 8 | (_Unwind_Exception_Class) 'N') + << 8 | (_Unwind_Exception_Class) 'U') + << 8 | (_Unwind_Exception_Class) 'C') + << 8 | (_Unwind_Exception_Class) 'J') + << 8 | (_Unwind_Exception_Class) 'A') + << 8 | (_Unwind_Exception_Class) 'V') + << 8 | (_Unwind_Exception_Class) 'A'); + + +static inline java_exception_header * +get_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast(exc + 1) - 1; } -/* Compiler hook to return a pointer to java exception object. The value - is cleared, so if the exception needs to be rethrown, it should be set - again */ +/* Perform a throw, Java style. Throw will unwind through this call, + so there better not be any handlers or exception thrown here. */ -extern "C" void * -_Jv_exception_info (void) +extern "C" void +_Jv_Throw (jthrowable value) { - java_eh_info *info = *(__get_eh_info ()); - void *ptr; + /* FIXME: Use the proper API to the collector. */ + java_exception_header *xh + = static_cast(GC_malloc (sizeof (*xh))); + + if (value == NULL) + value = new java::lang::NullPointerException (); + xh->value = value; - if (info == NULL) - abort (); + xh->unwindHeader.exception_class = __gcj_exception_class; + xh->unwindHeader.exception_cleanup = NULL; - ptr = info->value; + /* We're happy with setjmp/longjmp exceptions or region-based + exception handlers: entry points are provided here for both. */ + _Unwind_Reason_Code code; +#ifdef SJLJ_EXCEPTIONS + code = _Unwind_SjLj_RaiseException (&xh->unwindHeader); +#else + code = _Unwind_RaiseException (&xh->unwindHeader); +#endif - /* clear the value so another throw is an error */ - info->value = NULL; + /* FIXME: If code == _URC_END_OF_STACK, then we reached top of + stack without finding a handler for the exception. I seem to + recall that Java has specific rules to handle this. - return ptr; + If code is something else, we encountered some sort of heinous + lossage, from which we could not recover. As is the way of such + things we'll almost certainly have crashed before now, rather + than actually being able to diagnose the problem. */ + abort (); } + +// ??? These ought to go somewhere else dwarf2 or dwarf2eh related. + +// Pointer encodings. +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 + +static unsigned int +size_of_encoded_value (unsigned char encoding) +{ + switch (encoding & 0x07) + { + case DW_EH_PE_absptr: + return sizeof (void *); + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + } + abort (); +} +static const unsigned char * +read_encoded_value (_Unwind_Context *context, unsigned char encoding, + const unsigned char *p, _Unwind_Ptr *val) +{ + union unaligned + { + void *ptr; + unsigned u2 __attribute__ ((mode (HI))); + unsigned u4 __attribute__ ((mode (SI))); + unsigned u8 __attribute__ ((mode (DI))); + signed s2 __attribute__ ((mode (HI))); + signed s4 __attribute__ ((mode (SI))); + signed s8 __attribute__ ((mode (DI))); + } __attribute__((__packed__)); + + union unaligned *u = (union unaligned *) p; + _Unwind_Ptr result; + + switch (encoding & 0x0f) + { + case DW_EH_PE_absptr: + result = (_Unwind_Ptr) u->ptr; + p += sizeof (void *); + break; + + case DW_EH_PE_uleb128: + { + unsigned int shift = 0; + unsigned char byte; + + result = 0; + do + { + byte = *p++; + result |= (_Unwind_Ptr)(byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + } + break; + + case DW_EH_PE_sleb128: + { + unsigned int shift = 0; + unsigned char byte; + + result = 0; + do + { + byte = *p++; + result |= (_Unwind_Ptr)(byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) + result |= -(1L << shift); + } + break; + + case DW_EH_PE_udata2: + result = u->u2; + p += 2; + break; + case DW_EH_PE_udata4: + result = u->u4; + p += 4; + break; + case DW_EH_PE_udata8: + result = u->u8; + p += 8; + break; + + case DW_EH_PE_sdata2: + result = u->s2; + p += 2; + break; + case DW_EH_PE_sdata4: + result = u->s4; + p += 4; + break; + case DW_EH_PE_sdata8: + result = u->s8; + p += 8; + break; + + default: + abort (); + } -/* Allocate an exception info structure for java. Called the first time - an exception is thrown. */ + if (result != 0) + switch (encoding & 0xf0) + { + case DW_EH_PE_absptr: + break; -extern "C" void -_Jv_eh_alloc () -{ - /* FIXME: we should use _Jv_AllocBytes here. However, libgcc2 - apparently can sometimes free() this value itself. */ - java_eh_info *p = (java_eh_info *) malloc (sizeof (java_eh_info)); - if (p == 0) - abort (); + case DW_EH_PE_pcrel: + // Define as relative to the beginning of the pointer. + result += (_Unwind_Ptr) u; + break; + + case DW_EH_PE_textrel: + case DW_EH_PE_datarel: + // FIXME. + abort (); - p->value = 0; - java_eh_info ** info_ptr = __get_eh_info (); + case DW_EH_PE_funcrel: + result += _Unwind_GetRegionStart (context); + break; - /* There should NOT be an exception info pointer already. */ - if (*info_ptr != NULL) - abort (); + default: + abort (); + } - *info_ptr = p; + *val = result; + return p; } -/* Deallocate the current exception info structure. Called at shutdown time. */ +static inline const unsigned char * +read_uleb128 (const unsigned char *p, _Unwind_Ptr *val) +{ + return read_encoded_value (0, DW_EH_PE_uleb128, p, val); +} -extern "C" void -_Jv_eh_free () +static inline const unsigned char * +read_sleb128 (const unsigned char *p, _Unwind_Ptr *val) { - java_eh_info ** info_ptr = __get_eh_info (); - if (*info_ptr == NULL) - abort (); - - /* FIXME: ideally we should just let the GC handle this. */ - free (*info_ptr); - *info_ptr = NULL; + return read_encoded_value (0, DW_EH_PE_sleb128, p, val); } -/* Initialize an __eh_info structure with this libraries matching info. */ + +struct lsda_header_info +{ + _Unwind_Ptr Start; + _Unwind_Ptr LPStart; + const unsigned char *TType; + const unsigned char *action_table; + unsigned char ttype_encoding; + unsigned char call_site_encoding; +}; + +static const unsigned char * +parse_lsda_header (_Unwind_Context *context, const unsigned char *p, + lsda_header_info *info) +{ + _Unwind_Ptr tmp; + unsigned char lpstart_encoding; + + info->Start = (context ? _Unwind_GetRegionStart (context) : 0); -extern "C" void -_Jv_setup_eh_info (__eh_info *) + // Find @LPStart, the base to which landing pad offsets are relative. + lpstart_encoding = *p++; + if (lpstart_encoding != DW_EH_PE_omit) + p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart); + else + info->LPStart = info->Start; + + // Find @TType, the base of the handler and exception spec type data. + info->ttype_encoding = *p++; + if (info->ttype_encoding != DW_EH_PE_omit) + { + p = read_uleb128 (p, &tmp); + info->TType = p + tmp; + } + else + info->TType = 0; + + // The encoding and length of the call-site table; the action table + // immediately follows. + info->call_site_encoding = *p++; + p = read_uleb128 (p, &tmp); + info->action_table = p + tmp; + + return p; +} + +static jclass +get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i) { + _Unwind_Ptr ptr; + + i *= size_of_encoded_value (info->ttype_encoding); + read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr); + + return reinterpret_cast(ptr); } -/* Perform a throw, Java style. Throw will unwind through this call, - so there better not be any handlers or exception thrown here. */ +// Using a different personality function name causes link failures +// when trying to mix code using different exception handling models. #ifdef SJLJ_EXCEPTIONS -#define _Jv_Throw _Jv_Sjlj_Throw +#define PERSONALITY_FUNCTION __gcj_personality_sj0 +#define __builtin_eh_return_data_regno(x) x +#else +#define PERSONALITY_FUNCTION __gcj_personality_v0 #endif -extern "C" void -_Jv_Throw (jthrowable value) +extern "C" _Unwind_Reason_Code +PERSONALITY_FUNCTION (int version, + _Unwind_Action actions, + _Unwind_Exception_Class exception_class, + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) { - if (value == NULL) - value = new java::lang::NullPointerException; - java_eh_info *ehinfo = *(__get_eh_info ()); - if (ehinfo == NULL) + java_exception_header *xh = get_exception_header_from_ue (ue_header); + + lsda_header_info info; + const unsigned char *language_specific_data; + const unsigned char *action_record; + const unsigned char *p; + _Unwind_Ptr landing_pad, ip; + int handler_switch_value; + bool saw_cleanup; + bool saw_handler; + + + // Interface version check. + if (version != 1) + return _URC_FATAL_PHASE1_ERROR; + + // Shortcut for phase 2 found handler for domestic exception. + if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) + && exception_class == __gcj_exception_class) { - _Jv_eh_alloc (); - ehinfo = *(__get_eh_info ()); + handler_switch_value = xh->handlerSwitchValue; + landing_pad = xh->landingPad; + goto install_context; } - ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher; - ehinfo->eh_info.language = EH_LANG_Java; - ehinfo->eh_info.version = 1; - ehinfo->value = value; -/* We're happy with setjmp/longjmp exceptions or region-based - exception handlers: entry points are provided here for both. */ + // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of + // the stack trace for this exception. This will only collect Java + // frames, but perhaps that is acceptable. + // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site + // index instead of a PC value. We could perhaps arrange for + // _Unwind_GetRegionStart to return context->fc->jbuf[1], which + // is the address of the handler label for __builtin_longjmp, but + // there is no solution for DONT_USE_BUILTIN_SETJMP. + + language_specific_data = (const unsigned char *) + _Unwind_GetLanguageSpecificData (context); + + // If no LSDA, then there are no handlers or cleanups. + if (! language_specific_data) + return _URC_CONTINUE_UNWIND; + + // Parse the LSDA header. + p = parse_lsda_header (context, language_specific_data, &info); + ip = _Unwind_GetIP (context) - 1; + landing_pad = 0; + action_record = 0; + handler_switch_value = 0; + #ifdef SJLJ_EXCEPTIONS - __sjthrow (); + // The given "IP" is an index into the call-site table, with two + // exceptions -- -1 means no-action, and 0 means terminate. But + // since we're using uleb128 values, we've not got random access + // to the array. + if ((int) ip <= 0) + return _URC_CONTINUE_UNWIND; + else + { + _Unwind_Ptr cs_lp, cs_action; + do + { + p = read_uleb128 (p, &cs_lp); + p = read_uleb128 (p, &cs_action); + } + while (--ip); + + // Can never have null landing pad for sjlj -- that would have + // been indicated by a -1 call site index. + landing_pad = cs_lp + 1; + if (cs_action) + action_record = info.action_table + cs_action - 1; + goto found_something; + } #else - __throw (); -#endif -} + // Search the call-site table for the action associated with this IP. + while (p < info.action_table) + { + _Unwind_Ptr cs_start, cs_len, cs_lp, cs_action; + + // Note that all call-site encodings are "absolute" displacements. + p = read_encoded_value (0, info.call_site_encoding, p, &cs_start); + p = read_encoded_value (0, info.call_site_encoding, p, &cs_len); + p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp); + p = read_uleb128 (p, &cs_action); + + // The table is sorted, so if we've passed the ip, stop. + if (ip < info.Start + cs_start) + p = info.action_table; + else if (ip < info.Start + cs_start + cs_len) + { + if (cs_lp) + landing_pad = info.LPStart + cs_lp; + if (cs_action) + action_record = info.action_table + cs_action - 1; + goto found_something; + } + } +#endif // SJLJ_EXCEPTIONS -#ifdef USE_WIN32_SIGNALLING + // If ip is not present in the table, C++ would call terminate. + // ??? It is perhaps better to tweek the LSDA so that no-action + // is mapped to no-entry for Java. + return _URC_CONTINUE_UNWIND; -// This is a mangled version of _Jv_Throw and __sjthrow except -// rather than calling longjmp, it returns a pointer to the jmp buffer + found_something: + saw_cleanup = false; + saw_handler = false; -extern "C" int * -win32_get_restart_frame (void *value) -{ - struct eh_context *eh = (struct eh_context *)__get_eh_context (); - void ***dhc = &eh->dynamic_handler_chain; - - java_eh_info *ehinfo = *(__get_eh_info ()); - if (ehinfo == NULL) + if (landing_pad == 0) { - _Jv_eh_alloc (); - ehinfo = *(__get_eh_info ()); + // If ip is present, and has a null landing pad, there are + // no cleanups or handlers to be run. + } + else if (action_record == 0) + { + // If ip is present, has a non-null landing pad, and a null + // action table offset, then there are only cleanups present. + // Cleanups use a zero switch value, as set above. + saw_cleanup = true; + } + else + { + // Otherwise we have a catch handler. + signed long ar_filter, ar_disp; + + while (1) + { + _Unwind_Ptr tmp; + + p = action_record; + p = read_sleb128 (p, &tmp); ar_filter = tmp; + read_sleb128 (p, &tmp); ar_disp = tmp; + + if (ar_filter == 0) + { + // Zero filter values are cleanups. + saw_cleanup = true; + } + + // During forced unwinding, we only run cleanups. With a + // foreign exception class, we have no class info to match. + else if ((actions & _UA_FORCE_UNWIND) + || exception_class != __gcj_exception_class) + ; + + else if (ar_filter > 0) + { + // Positive filter values are handlers. + + jclass catch_type = get_ttype_entry (context, &info, ar_filter); + + // The catch_type is either a (java::lang::Class*) or + // is one more than a (Utf8Const*). + if ((size_t)catch_type & 1) + catch_type = _Jv_FindClass ((Utf8Const*)catch_type - 1, NULL); + + if (_Jv_IsInstanceOf (xh->value, catch_type)) + { + handler_switch_value = ar_filter; + saw_handler = true; + break; + } + } + else + { + // Negative filter values are exception specifications, + // which Java does not use. + // ??? Perhaps better to make them an index into a table + // of null-terminated strings instead of playing games + // with Utf8Const+1 as above. + abort (); + } + + if (ar_disp == 0) + break; + action_record = p + ar_disp; + } } - ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher; - ehinfo->eh_info.language = EH_LANG_Java; - ehinfo->eh_info.version = 1; - ehinfo->value = value; - - // FIXME: Run clean ups? - int *jmpbuf = (int*)&(*dhc)[2]; + if (! saw_handler && ! saw_cleanup) + return _URC_CONTINUE_UNWIND; - *dhc = (void**)(*dhc)[0]; + if (actions & _UA_SEARCH_PHASE) + { + if (! saw_handler) + return _URC_CONTINUE_UNWIND; + + // For domestic exceptions, we cache data from phase 1 for phase 2. + if (exception_class == __gcj_exception_class) + { + xh->handlerSwitchValue = handler_switch_value; + xh->landingPad = landing_pad; + } + return _URC_HANDLER_FOUND; + } - return jmpbuf; + install_context: + _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), + (_Unwind_Ptr) &xh->unwindHeader); + _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), + handler_switch_value); + _Unwind_SetIP (context, landing_pad); + return _URC_INSTALL_CONTEXT; } - -#endif /* USE_WIN32_SIGNALLING */ diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h index 2ae65e3e8df..62554514b54 100644 --- a/libjava/gcj/javaprims.h +++ b/libjava/gcj/javaprims.h @@ -369,7 +369,6 @@ extern "C" jsize _Jv_GetStringUTFLength (jstring); extern "C" jsize _Jv_GetStringUTFRegion (jstring, jsize, jsize, char *); extern "C" void _Jv_Throw (jthrowable) __attribute__ ((__noreturn__)); -extern "C" void _Jv_Sjlj_Throw (jthrowable) __attribute__ ((__noreturn__)); extern "C" void* _Jv_Malloc (jsize) __attribute__((__malloc__)); extern "C" void* _Jv_Realloc (void *, jsize); extern "C" void _Jv_Free (void*); diff --git a/libjava/libgcj.spec.in b/libjava/libgcj.spec.in index 694418eb373..5a21e7a699a 100644 --- a/libjava/libgcj.spec.in +++ b/libjava/libgcj.spec.in @@ -6,7 +6,7 @@ %rename lib liborig *lib: -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig) -*jc1: @DIVIDESPEC@ @EXCEPTIONSPEC@ @JC1GCSPEC@ -fasynchronous-exceptions +*jc1: @DIVIDESPEC@ @JC1GCSPEC@ # # On some systems we force in a data_start symbol so that the GC will work diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8ed8178a1d7..ac698159be6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2001-03-28 Richard Henderson + + IA-64 ABI Exception Handling: + * acinclude.m4 (GLIBCPP_ENABLE_SJLJ_EXCEPTIONS): New. + * configure.in: Use it. + * Makefile.in, aclocal.m4, config.h.in, configure: Regenerate. + * libsupc++/Makefile.am (sources): Update files list. + * libsupc++/Makefile.in: Regenerate. + * libsupc++/eh_alloc.cc, libsupc++/eh_aux_runtime.cc: New files. + * libsupc++/eh_catch.cc, libsupc++/eh_exception.cc: New files. + * libsupc++/eh_globals.cc, libsupc++/eh_personality.cc: New files. + * libsupc++/eh_terminate.cc, libsupc++/eh_throw.cc: New files. + * libsupc++/exception_support.cc: Remove. + * libsupc++/exception_support.h: Remove. + * libsupc++/pure.cc: Use std::terminate. + * libsupc++/tinfo2.cc (__throw_type_match_rtti_2): Remove. + (__is_pointer): Remove. + * libsupc++/unwind-cxx.h: New file. + * libsupc++/vec.cc (uncatch_exception): Update for new abi. + 2001-03-27 Alexandre Oliva * libsupc++/Makefile.am (CXXLINK): Use CXX again, and choose diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in index ecaede4d8f1..29ebfd1f730 100644 --- a/libstdc++-v3/Makefile.in +++ b/libstdc++-v3/Makefile.in @@ -134,48 +134,7 @@ MULTICLEAN = true # Work around what appears to be a GNU make bug handling MAKEFLAGS # values defined in terms of make variables, as is the case for CC and # friends when we are called from the top level Makefile. -AM_MAKEFLAGS = \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ - "CC_FOR_TARGET=$(CC_FOR_TARGET)" \ - "CFLAGS=$(CFLAGS)" \ - "CXXFLAGS=$(CXXFLAGS)" \ - "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ - "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ - "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ - "LDFLAGS=$(LDFLAGS)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ - "MAKE=$(MAKE)" \ - "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ - "PICFLAG=$(PICFLAG)" \ - "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ - "SHELL=$(SHELL)" \ - "EXPECT=$(EXPECT)" \ - "RUNTEST=$(RUNTEST)" \ - "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ - "exec_prefix=$(exec_prefix)" \ - "infodir=$(infodir)" \ - "libdir=$(libdir)" \ - "includedir=$(includedir)" \ - "prefix=$(prefix)" \ - "tooldir=$(tooldir)" \ - "AR=$(AR)" \ - "AS=$(AS)" \ - "CC=$(CC)" \ - "CXX=$(CXX)" \ - "LD=$(LD)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "PICFLAG=$(PICFLAG)" \ - "RANLIB=$(RANLIB)" \ - "NM=$(NM)" \ - "NM_FOR_BUILD=$(NM_FOR_BUILD)" \ - "NM_FOR_TARGET=$(NM_FOR_TARGET)" \ - "DESTDIR=$(DESTDIR)" \ - "WERROR=$(WERROR)" +AM_MAKEFLAGS = "AR_FLAGS=$(AR_FLAGS)" "CC_FOR_BUILD=$(CC_FOR_BUILD)" "CC_FOR_TARGET=$(CC_FOR_TARGET)" "CFLAGS=$(CFLAGS)" "CXXFLAGS=$(CXXFLAGS)" "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" "INSTALL=$(INSTALL)" "INSTALL_DATA=$(INSTALL_DATA)" "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" "LDFLAGS=$(LDFLAGS)" "LIBCFLAGS=$(LIBCFLAGS)" "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" "MAKE=$(MAKE)" "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" "PICFLAG=$(PICFLAG)" "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" "SHELL=$(SHELL)" "EXPECT=$(EXPECT)" "RUNTEST=$(RUNTEST)" "RUNTESTFLAGS=$(RUNTESTFLAGS)" "exec_prefix=$(exec_prefix)" "infodir=$(infodir)" "libdir=$(libdir)" "includedir=$(includedir)" "prefix=$(prefix)" "tooldir=$(tooldir)" "AR=$(AR)" "AS=$(AS)" "CC=$(CC)" "CXX=$(CXX)" "LD=$(LD)" "LIBCFLAGS=$(LIBCFLAGS)" "PICFLAG=$(PICFLAG)" "RANLIB=$(RANLIB)" "NM=$(NM)" "NM_FOR_BUILD=$(NM_FOR_BUILD)" "NM_FOR_TARGET=$(NM_FOR_TARGET)" "DESTDIR=$(DESTDIR)" "WERROR=$(WERROR)" ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 CONFIG_HEADER = config.h @@ -353,7 +312,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index c3b3a06ac43..2ba509f70bf 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -1257,6 +1257,66 @@ AC_DEFUN(GLIBCPP_ENABLE_THREADS, [ ]) +dnl +dnl Check for exception handling support. If an explicit enable/disable +dnl sjlj exceptions is given, we don't have to detect. Otherwise the +dnl target may or may not support call frame exceptions. +dnl +dnl GLIBCPP_ENABLE_SJLJ_EXCEPTIONS +dnl --enable-sjlj-exceptions forces the use of builtin setjmp. +dnl --disable-sjlj-exceptions forces the use of call frame unwinding. +dnl +dnl Define _GLIBCPP_SJLJ_EXCEPTIONS if the compiler is configured for it. +dnl +AC_DEFUN(GLIBCPP_ENABLE_SJLJ_EXCEPTIONS, [ + AC_MSG_CHECKING([for exception model to use]) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_ARG_ENABLE(sjlj-exceptions, + [ --enable-sjlj-exceptions force use of builtin_setjmp for exceptions], + [:], + [dnl Botheration. Now we've got to detect the exception model. + dnl Link tests against libgcc.a are problematic since -- at least + dnl as of this writing -- we've not been given proper -L bits for + dnl single-tree newlib and libgloss. + dnl + dnl This is what AC_TRY_COMPILE would do if it didn't delete the + dnl conftest files before we got a change to grep them first. + cat > conftest.$ac_ext << EOF +[#]line __oline__ "configure" +struct S { ~S(); }; +void bar(); +void foo() +{ + S s; + bar(); +} +EOF + old_CXXFLAGS="$CXXFLAGS" + CXXFLAGS=-S + if AC_TRY_EVAL(ac_compile); then + if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes + elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no + fi + fi + CXXFLAGS="$old_CXXFLAGS" + rm -f conftest*]) + if test x$enable_sjlj_exceptions = xyes; then + AC_DEFINE(_GLIBCPP_SJLJ_EXCEPTIONS, 1, + [Define if the compiler is configured for setjmp/longjmp exceptions.]) + ac_exception_model_name=sjlj + elif test x$enable_sjlj_exceptions = xno; then + ac_exception_model_name="call frame" + else + AC_MSG_ERROR([unable to detect exception model]) + fi + AC_LANG_RESTORE + AC_MSG_RESULT($ac_exception_model_name) +]) + + dnl dnl Check for template specializations for the 'long long' type extension. dnl diff --git a/libstdc++-v3/aclocal.m4 b/libstdc++-v3/aclocal.m4 index b215cba1d64..f16196a8887 100644 --- a/libstdc++-v3/aclocal.m4 +++ b/libstdc++-v3/aclocal.m4 @@ -1269,6 +1269,66 @@ AC_DEFUN(GLIBCPP_ENABLE_THREADS, [ ]) +dnl +dnl Check for exception handling support. If an explicit enable/disable +dnl sjlj exceptions is given, we don't have to detect. Otherwise the +dnl target may or may not support call frame exceptions. +dnl +dnl GLIBCPP_ENABLE_SJLJ_EXCEPTIONS +dnl --enable-sjlj-exceptions forces the use of builtin setjmp. +dnl --disable-sjlj-exceptions forces the use of call frame unwinding. +dnl +dnl Define _GLIBCPP_SJLJ_EXCEPTIONS if the compiler is configured for it. +dnl +AC_DEFUN(GLIBCPP_ENABLE_SJLJ_EXCEPTIONS, [ + AC_MSG_CHECKING([for exception model to use]) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_ARG_ENABLE(sjlj-exceptions, + [ --enable-sjlj-exceptions force use of builtin_setjmp for exceptions], + [:], + [dnl Botheration. Now we've got to detect the exception model. + dnl Link tests against libgcc.a are problematic since -- at least + dnl as of this writing -- we've not been given proper -L bits for + dnl single-tree newlib and libgloss. + dnl + dnl This is what AC_TRY_COMPILE would do if it didn't delete the + dnl conftest files before we got a change to grep them first. + cat > conftest.$ac_ext << EOF +[#]line __oline__ "configure" +struct S { ~S(); }; +void bar(); +void foo() +{ + S s; + bar(); +} +EOF + old_CXXFLAGS="$CXXFLAGS" + CXXFLAGS=-S + if AC_TRY_EVAL(ac_compile); then + if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes + elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no + fi + fi + CXXFLAGS="$old_CXXFLAGS" + rm -f conftest*]) + if test x$enable_sjlj_exceptions = xyes; then + AC_DEFINE(_GLIBCPP_SJLJ_EXCEPTIONS, 1, + [Define if the compiler is configured for setjmp/longjmp exceptions.]) + ac_exception_model_name=sjlj + elif test x$enable_sjlj_exceptions = xno; then + ac_exception_model_name="call frame" + else + AC_MSG_ERROR([unable to detect exception model]) + fi + AC_LANG_RESTORE + AC_MSG_RESULT($ac_exception_model_name) +]) + + dnl dnl Check for template specializations for the 'long long' type extension. dnl diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index d424291054a..a16c1e1148c 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -546,6 +546,9 @@ /* Version number of package */ #undef VERSION +/* Define if the compiler is configured for setjmp/longjmp exceptions. */ +#undef _GLIBCPP_SJLJ_EXCEPTIONS + /* Define if sigsetjmp is available. */ #undef HAVE_SIGSETJMP diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 4737318aa5f..dfdd9d41919 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -57,6 +57,8 @@ ac_help="$ac_help ac_help="$ac_help --enable-cxx-flags=FLAGS pass compiler FLAGS when building library; [default=none]" +ac_help="$ac_help + --enable-sjlj-exceptions force use of builtin_setjmp for exceptions" ac_help="$ac_help --with-gxx-include-dir the installation directory for include files" ac_help="$ac_help @@ -78,7 +80,6 @@ program_suffix=NONE program_transform_name=s,x,x, silent= site= -sitefile= srcdir= target=NONE verbose= @@ -193,7 +194,6 @@ Configuration: --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages - --site-file=FILE use FILE as the site file --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX @@ -364,11 +364,6 @@ EOF -site=* | --site=* | --sit=*) site="$ac_optarg" ;; - -site-file | --site-file | --site-fil | --site-fi | --site-f) - ac_prev=sitefile ;; - -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) - sitefile="$ac_optarg" ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) @@ -534,16 +529,12 @@ fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. -if test -z "$sitefile"; then - if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -else - CONFIG_SITE="$sitefile" fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then @@ -657,7 +648,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:661: checking host system type" >&5 +echo "configure:652: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -678,7 +669,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:682: checking target system type" >&5 +echo "configure:673: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -696,7 +687,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:700: checking build system type" >&5 +echo "configure:691: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -747,7 +738,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:751: checking for a BSD compatible install" >&5 +echo "configure:742: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -800,7 +791,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:804: checking whether build environment is sane" >&5 +echo "configure:795: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -857,7 +848,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:861: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:852: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -890,12 +881,12 @@ else fi echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:894: checking for Cygwin environment" >&5 +echo "configure:885: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:901: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else @@ -923,19 +914,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:927: checking for mingw32 environment" >&5 +echo "configure:918: checking for mingw32 environment" >&5 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:930: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -987,7 +978,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:991: checking for working aclocal" >&5 +echo "configure:982: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1000,7 +991,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:1004: checking for working autoconf" >&5 +echo "configure:995: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1013,7 +1004,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:1017: checking for working automake" >&5 +echo "configure:1008: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1026,7 +1017,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:1030: checking for working autoheader" >&5 +echo "configure:1021: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1039,7 +1030,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:1043: checking for working makeinfo" >&5 +echo "configure:1034: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1074,7 +1065,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1078: checking for $ac_word" >&5 +echo "configure:1069: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1104,7 +1095,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1108: checking for $ac_word" >&5 +echo "configure:1099: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1153,7 +1144,7 @@ fi fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1157: checking whether we are using GNU C" >&5 +echo "configure:1148: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1162,7 +1153,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1177,7 +1168,7 @@ if test $ac_cv_prog_gcc = yes; then ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1181: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1172: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1222,7 +1213,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1226: checking for $ac_word" >&5 +echo "configure:1217: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX_libstdcxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1257,7 +1248,7 @@ CXX=$CXX_libstdcxx test -z "$CXX" && { echo "configure: error: no acceptable c++ found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 -echo "configure:1261: checking whether we are using GNU C++" >&5 +echo "configure:1252: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1266,7 +1257,7 @@ else yes; #endif EOF -if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1270: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1261: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no @@ -1281,7 +1272,7 @@ if test $ac_cv_prog_gxx = yes; then ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 -echo "configure:1285: checking whether ${CXX-g++} accepts -g" >&5 +echo "configure:1276: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1312,7 +1303,7 @@ fi # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1316: checking for $ac_word" >&5 +echo "configure:1307: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1344,7 +1335,7 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1348: checking for $ac_word" >&5 +echo "configure:1339: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1376,7 +1367,7 @@ fi # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1380: checking for $ac_word" >&5 +echo "configure:1371: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1408,7 +1399,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1412: checking for $ac_word" >&5 +echo "configure:1403: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1453,7 +1444,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1457: checking for a BSD compatible install" >&5 +echo "configure:1448: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1507,7 +1498,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:1511: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:1502: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -1541,7 +1532,7 @@ fi echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:1545: checking for executable suffix" >&5 +echo "configure:1536: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1551,10 +1542,10 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:1555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:1546: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *.c | *.o | *.obj) ;; *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; esac done @@ -1672,7 +1663,7 @@ ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 -echo "configure:1676: checking for ld used by GCC" >&5 +echo "configure:1667: checking for ld used by GCC" >&5 case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw @@ -1702,10 +1693,10 @@ echo "configure:1676: checking for ld used by GCC" >&5 esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:1706: checking for GNU ld" >&5 +echo "configure:1697: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:1709: checking for non-GNU ld" >&5 +echo "configure:1700: checking for non-GNU ld" >&5 fi if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1740,7 +1731,7 @@ else fi test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:1744: checking if the linker ($LD) is GNU ld" >&5 +echo "configure:1735: checking if the linker ($LD) is GNU ld" >&5 if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1757,7 +1748,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 -echo "configure:1761: checking for $LD option to reload object files" >&5 +echo "configure:1752: checking for $LD option to reload object files" >&5 if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1769,7 +1760,7 @@ reload_flag=$lt_cv_ld_reload_flag test -n "$reload_flag" && reload_flag=" $reload_flag" echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 -echo "configure:1773: checking for BSD-compatible nm" >&5 +echo "configure:1764: checking for BSD-compatible nm" >&5 if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1807,7 +1798,7 @@ NM="$lt_cv_path_NM" echo "$ac_t""$NM" 1>&6 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1811: checking whether ln -s works" >&5 +echo "configure:1802: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1828,7 +1819,7 @@ else fi echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6 -echo "configure:1832: checking how to recognise dependant libraries" >&5 +echo "configure:1823: checking how to recognise dependant libraries" >&5 if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1983,13 +1974,13 @@ file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method echo $ac_n "checking for object suffix""... $ac_c" 1>&6 -echo "configure:1987: checking for object suffix" >&5 +echo "configure:1978: checking for object suffix" >&5 if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftest* echo 'int i = 1;' > conftest.$ac_ext -if { (eval echo configure:1993: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then for ac_file in conftest.*; do case $ac_file in *.c) ;; @@ -2013,7 +2004,7 @@ case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 -echo "configure:2017: checking for ${ac_tool_prefix}file" >&5 +echo "configure:2008: checking for ${ac_tool_prefix}file" >&5 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2075,7 +2066,7 @@ fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then echo $ac_n "checking for file""... $ac_c" 1>&6 -echo "configure:2079: checking for file" >&5 +echo "configure:2070: checking for file" >&5 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2146,7 +2137,7 @@ esac # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2150: checking for $ac_word" >&5 +echo "configure:2141: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2178,7 +2169,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2182: checking for $ac_word" >&5 +echo "configure:2173: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2213,7 +2204,7 @@ fi # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2217: checking for $ac_word" >&5 +echo "configure:2208: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2245,7 +2236,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2249: checking for $ac_word" >&5 +echo "configure:2240: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2312,8 +2303,8 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 2316 "configure"' > conftest.$ac_ext - if { (eval echo configure:2317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + echo '#line 2307 "configure"' > conftest.$ac_ext + if { (eval echo configure:2308: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" @@ -2334,7 +2325,7 @@ case $host in SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 -echo "configure:2338: checking whether the C compiler needs -belf" >&5 +echo "configure:2329: checking whether the C compiler needs -belf" >&5 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2347,14 +2338,14 @@ ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$a cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* lt_cv_cc_needs_belf=yes else @@ -2384,7 +2375,7 @@ echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 esac echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 -echo "configure:2388: checking how to run the C++ preprocessor" >&5 +echo "configure:2379: checking how to run the C++ preprocessor" >&5 if test -z "$CXXCPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2397,12 +2388,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross CXXCPP="${CXX-g++} -E" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2406: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2397: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2537,7 +2528,7 @@ exec 5>>./config.log echo $ac_n "checking for GNU make""... $ac_c" 1>&6 -echo "configure:2541: checking for GNU make" >&5 +echo "configure:2532: checking for GNU make" >&5 if eval "test \"`echo '$''{'_cv_gnu_make_command'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2571,7 +2562,7 @@ echo "$ac_t""$_cv_gnu_make_command" 1>&6 ; if test ! -f stamp-sanity-compiler; then echo $ac_n "checking for g++ that will successfully compile libstdc++-v3""... $ac_c" 1>&6 -echo "configure:2575: checking for g++ that will successfully compile libstdc++-v3" >&5 +echo "configure:2566: checking for g++ that will successfully compile libstdc++-v3" >&5 ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -2581,7 +2572,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext <= 3 @@ -2635,7 +2626,7 @@ esac echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:2639: checking how to run the C preprocessor" >&5 +echo "configure:2630: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -2650,13 +2641,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2660: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2667,13 +2658,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2677: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2668: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2684,13 +2675,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2694: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2685: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2716,7 +2707,7 @@ echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for cstdio to use""... $ac_c" 1>&6 -echo "configure:2720: checking for cstdio to use" >&5 +echo "configure:2711: checking for cstdio to use" >&5 # Check whether --enable-cstdio or --disable-cstdio was given. if test "${enable_cstdio+set}" = set; then enableval="$enable_cstdio" @@ -2740,17 +2731,17 @@ fi # see if we are on a system with libio native (ie, linux) ac_safe=`echo "libio.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for libio.h""... $ac_c" 1>&6 -echo "configure:2744: checking for libio.h" >&5 +echo "configure:2735: checking for libio.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2754: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2745: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2780,9 +2771,9 @@ fi case "$target" in *-*-linux*) echo $ac_n "checking for glibc version >= 2.2""... $ac_c" 1>&6 -echo "configure:2784: checking for glibc version >= 2.2" >&5 +echo "configure:2775: checking for glibc version >= 2.2" >&5 cat > conftest.$ac_ext < @@ -2896,7 +2887,7 @@ fi echo $ac_n "checking for clocale to use""... $ac_c" 1>&6 -echo "configure:2900: checking for clocale to use" >&5 +echo "configure:2891: checking for clocale to use" >&5 # Check whether --enable-clocale or --disable-clocale was given. if test "${enable_clocale+set}" = set; then enableval="$enable_clocale" @@ -2964,12 +2955,12 @@ fi # Check for the existence of functions used if long long is enabled. echo $ac_n "checking for strtoll""... $ac_c" 1>&6 -echo "configure:2968: checking for strtoll" >&5 +echo "configure:2959: checking for strtoll" >&5 if eval "test \"`echo '$''{'ac_cv_func_strtoll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strtoll=yes" else @@ -3013,12 +3004,12 @@ ac_strtoll=no fi echo $ac_n "checking for strtoull""... $ac_c" 1>&6 -echo "configure:3017: checking for strtoull" >&5 +echo "configure:3008: checking for strtoull" >&5 if eval "test \"`echo '$''{'ac_cv_func_strtoull'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strtoull=yes" else @@ -3064,13 +3055,13 @@ fi # Check for lldiv_t, et. al. echo $ac_n "checking for lldiv_t declaration""... $ac_c" 1>&6 -echo "configure:3068: checking for lldiv_t declaration" >&5 +echo "configure:3059: checking for lldiv_t declaration" >&5 if eval "test \"`echo '$''{'glibcpp_lldiv_t_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3078,7 +3069,7 @@ int main() { lldiv_t mydivt; ; return 0; } EOF -if { (eval echo configure:3082: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_lldiv_t_use=yes else @@ -3100,7 +3091,7 @@ EOF fi echo $ac_n "checking for enabled long long""... $ac_c" 1>&6 -echo "configure:3104: checking for enabled long long" >&5 +echo "configure:3095: checking for enabled long long" >&5 if test x"$ac_strtoll" = xno || test x"$ac_strtoull" = xno; then enable_long_long=no; fi; @@ -3118,7 +3109,7 @@ EOF CFLAGS="$ac_save_CFLAGS" echo $ac_n "checking for c header strategy to use""... $ac_c" 1>&6 -echo "configure:3122: checking for c header strategy to use" >&5 +echo "configure:3113: checking for c header strategy to use" >&5 # Check whether --enable-cheaders or --disable-cheaders was given. if test "${enable_cheaders+set}" = set; then enableval="$enable_cheaders" @@ -3175,7 +3166,7 @@ fi echo $ac_n "checking for threads package to use""... $ac_c" 1>&6 -echo "configure:3179: checking for threads package to use" >&5 +echo "configure:3170: checking for threads package to use" >&5 # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" @@ -3267,6 +3258,65 @@ EXTRA_CXX_FLAGS="$enable_cxx_flags" + echo $ac_n "checking for exception model to use""... $ac_c" 1>&6 +echo "configure:3263: checking for exception model to use" >&5 + + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + + # Check whether --enable-sjlj-exceptions or --disable-sjlj-exceptions was given. +if test "${enable_sjlj_exceptions+set}" = set; then + enableval="$enable_sjlj_exceptions" + : +else + cat > conftest.$ac_ext << EOF +#line 3278 "configure" +struct S { ~S(); }; +void bar(); +void foo() +{ + S s; + bar(); +} +EOF + old_CXXFLAGS="$CXXFLAGS" + CXXFLAGS=-S + if { (eval echo configure:3289: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes + elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no + fi + fi + CXXFLAGS="$old_CXXFLAGS" + rm -f conftest* +fi + + if test x$enable_sjlj_exceptions = xyes; then + cat >> confdefs.h <<\EOF +#define _GLIBCPP_SJLJ_EXCEPTIONS 1 +EOF + + ac_exception_model_name=sjlj + elif test x$enable_sjlj_exceptions = xno; then + ac_exception_model_name="call frame" + else + { echo "configure: error: unable to detect exception model" 1>&2; exit 1; } + fi + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + + echo "$ac_t""$ac_exception_model_name" 1>&6 + + if test -n "$with_cross_host"; then # We are being configured with a cross compiler. AC_REPLACE_FUNCS @@ -3295,17 +3345,17 @@ if test -n "$with_cross_host"; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3299: checking for $ac_hdr" >&5 +echo "configure:3349: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3309: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3359: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3361,12 +3411,12 @@ done # used sections, first .eh_frame and now some of the glibc sections for # iconv). Bzzzzt. Thanks for playing, maybe next time. echo $ac_n "checking for ld that supports -Wl,--gc-sections""... $ac_c" 1>&6 -echo "configure:3365: checking for ld that supports -Wl,--gc-sections" >&5 +echo "configure:3415: checking for ld that supports -Wl,--gc-sections" >&5 if test "$cross_compiling" = yes; then ac_sectionLDflags=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_sectionLDflags=yes else @@ -3655,7 +3705,7 @@ EOF fi echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:3659: checking for main in -lm" >&5 +echo "configure:3709: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3663,14 +3713,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3700,12 +3750,12 @@ fi for ac_func in nan hypot hypotf atan2f expf copysignf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3704: checking for $ac_func" >&5 +echo "configure:3754: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3762,12 +3812,12 @@ done for ac_func in hypotl signbitl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3766: checking for $ac_func" >&5 +echo "configure:3816: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3824,7 +3874,7 @@ done echo $ac_n "checking for GNU C++ __complex__ support""... $ac_c" 1>&6 -echo "configure:3828: checking for GNU C++ __complex__ support" >&5 +echo "configure:3878: checking for GNU C++ __complex__ support" >&5 if eval "test \"`echo '$''{'glibcpp_cv_complex'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3838,7 +3888,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3901: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_complex=ok else @@ -3877,7 +3927,7 @@ EOF fi echo $ac_n "checking for GNU C++ __complex__ float support""... $ac_c" 1>&6 -echo "configure:3881: checking for GNU C++ __complex__ float support" >&5 +echo "configure:3931: checking for GNU C++ __complex__ float support" >&5 if eval "test \"`echo '$''{'glibcpp_cv_float_complex'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3910,14 +3960,14 @@ cross_compiling=$ac_cv_prog_cxx_cross }; EOB cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3971: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_float_complex=ok else @@ -3949,16 +3999,16 @@ EOF echo $ac_n "checking for mbstate_t""... $ac_c" 1>&6 -echo "configure:3953: checking for mbstate_t" >&5 +echo "configure:4003: checking for mbstate_t" >&5 cat > conftest.$ac_ext < int main() { mbstate_t teststate; ; return 0; } EOF -if { (eval echo configure:3962: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4012: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* have_mbstate_t=yes else @@ -3980,17 +4030,17 @@ EOF do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3984: checking for $ac_hdr" >&5 +echo "configure:4034: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3994: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4044: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4019,17 +4069,17 @@ done ac_safe=`echo "wctype.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for wctype.h""... $ac_c" 1>&6 -echo "configure:4023: checking for wctype.h" >&5 +echo "configure:4073: checking for wctype.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4033: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4056,16 +4106,16 @@ fi && test x"$enable_c_mbchar" != xno; then echo $ac_n "checking for WCHAR_MIN and WCHAR_MAX""... $ac_c" 1>&6 -echo "configure:4060: checking for WCHAR_MIN and WCHAR_MAX" >&5 +echo "configure:4110: checking for WCHAR_MIN and WCHAR_MAX" >&5 cat > conftest.$ac_ext < int main() { int i = WCHAR_MIN; int j = WCHAR_MAX; ; return 0; } EOF -if { (eval echo configure:4069: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4119: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* has_wchar_minmax=yes else @@ -4078,9 +4128,9 @@ rm -f conftest* echo "$ac_t""$has_wchar_minmax" 1>&6 echo $ac_n "checking for WEOF""... $ac_c" 1>&6 -echo "configure:4082: checking for WEOF" >&5 +echo "configure:4132: checking for WEOF" >&5 cat > conftest.$ac_ext < @@ -4089,7 +4139,7 @@ int main() { wint_t i = WEOF; ; return 0; } EOF -if { (eval echo configure:4093: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4143: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* has_weof=yes else @@ -4105,12 +4155,12 @@ rm -f conftest* wcsrtombs mbsrtowcs do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4109: checking for $ac_func" >&5 +echo "configure:4159: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4160,7 +4210,7 @@ done echo $ac_n "checking for ISO C99 wchar_t support""... $ac_c" 1>&6 -echo "configure:4164: checking for ISO C99 wchar_t support" >&5 +echo "configure:4214: checking for ISO C99 wchar_t support" >&5 if test x"$has_weof" = xyes && test x"$has_wchar_minmax" = xyes \ && test x"$ac_wfuncs" = xyes; then ac_isoC99_wchar_t=yes @@ -4171,17 +4221,17 @@ echo "configure:4164: checking for ISO C99 wchar_t support" >&5 ac_safe=`echo "iconv.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for iconv.h""... $ac_c" 1>&6 -echo "configure:4175: checking for iconv.h" >&5 +echo "configure:4225: checking for iconv.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4185: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4235: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4205,17 +4255,17 @@ fi ac_safe=`echo "langinfo.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for langinfo.h""... $ac_c" 1>&6 -echo "configure:4209: checking for langinfo.h" >&5 +echo "configure:4259: checking for langinfo.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4219: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4239,7 +4289,7 @@ fi echo $ac_n "checking for iconv in -liconv""... $ac_c" 1>&6 -echo "configure:4243: checking for iconv in -liconv" >&5 +echo "configure:4293: checking for iconv in -liconv" >&5 ac_lib_var=`echo iconv'_'iconv | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4247,7 +4297,7 @@ else ac_save_LIBS="$LIBS" LIBS="-liconv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4284,12 +4334,12 @@ fi for ac_func in iconv_open iconv_close iconv nl_langinfo do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4288: checking for $ac_func" >&5 +echo "configure:4338: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4342,7 +4392,7 @@ done LIBS="$ac_save_LIBS" echo $ac_n "checking for XPG2 wchar_t support""... $ac_c" 1>&6 -echo "configure:4346: checking for XPG2 wchar_t support" >&5 +echo "configure:4396: checking for XPG2 wchar_t support" >&5 if test x"$ac_has_iconv_h" = xyes && test x"$ac_has_langinfo_h" = xyes \ && test x"$ac_XPG2funcs" = xyes; then ac_XPG2_wchar_t=yes @@ -4352,7 +4402,7 @@ echo "configure:4346: checking for XPG2 wchar_t support" >&5 echo "$ac_t""$ac_XPG2_wchar_t" 1>&6 echo $ac_n "checking for enabled wchar_t specializations""... $ac_c" 1>&6 -echo "configure:4356: checking for enabled wchar_t specializations" >&5 +echo "configure:4406: checking for enabled wchar_t specializations" >&5 if test x"$ac_isoC99_wchar_t" = xyes \ && test x"$ac_XPG2_wchar_t" = xyes; then cat >> confdefs.h <<\EOF @@ -4436,17 +4486,17 @@ else do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4440: checking for $ac_hdr" >&5 +echo "configure:4490: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4450: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4500: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4497,10 +4547,10 @@ cross_compiling=$ac_cv_prog_cxx_cross # Check for -ffunction-sections -fdata-sections echo $ac_n "checking for g++ that supports -ffunction-sections -fdata-sections""... $ac_c" 1>&6 -echo "configure:4501: checking for g++ that supports -ffunction-sections -fdata-sections" >&5 +echo "configure:4551: checking for g++ that supports -ffunction-sections -fdata-sections" >&5 CXXFLAGS='-Werror -ffunction-sections -fdata-sections' cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_fdsections=yes else @@ -4565,12 +4615,12 @@ cross_compiling=$ac_cv_prog_cc_cross # used sections, first .eh_frame and now some of the glibc sections for # iconv). Bzzzzt. Thanks for playing, maybe next time. echo $ac_n "checking for ld that supports -Wl,--gc-sections""... $ac_c" 1>&6 -echo "configure:4569: checking for ld that supports -Wl,--gc-sections" >&5 +echo "configure:4619: checking for ld that supports -Wl,--gc-sections" >&5 if test "$cross_compiling" = yes; then ac_sectionLDflags=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_sectionLDflags=yes else @@ -4616,7 +4666,7 @@ fi echo $ac_n "checking for __builtin_abs declaration""... $ac_c" 1>&6 -echo "configure:4620: checking for __builtin_abs declaration" >&5 +echo "configure:4670: checking for __builtin_abs declaration" >&5 if test x${glibcpp_cv_func___builtin_abs_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_abs_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4631,14 +4681,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_abs(0); ; return 0; } EOF -if { (eval echo configure:4642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4692: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_abs_use=yes else @@ -4662,21 +4712,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_abs_use" 1>&6 if test x$glibcpp_cv_func___builtin_abs_use = x"yes"; then echo $ac_n "checking for __builtin_abs linkage""... $ac_c" 1>&6 -echo "configure:4666: checking for __builtin_abs linkage" >&5 +echo "configure:4716: checking for __builtin_abs linkage" >&5 if test x${glibcpp_cv_func___builtin_abs_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_abs_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_abs(0); ; return 0; } EOF -if { (eval echo configure:4680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_abs_link=yes else @@ -4702,7 +4752,7 @@ EOF echo $ac_n "checking for __builtin_fabsf declaration""... $ac_c" 1>&6 -echo "configure:4706: checking for __builtin_fabsf declaration" >&5 +echo "configure:4756: checking for __builtin_fabsf declaration" >&5 if test x${glibcpp_cv_func___builtin_fabsf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fabsf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4717,14 +4767,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_fabsf(0); ; return 0; } EOF -if { (eval echo configure:4728: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4778: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_fabsf_use=yes else @@ -4748,21 +4798,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_fabsf_use" 1>&6 if test x$glibcpp_cv_func___builtin_fabsf_use = x"yes"; then echo $ac_n "checking for __builtin_fabsf linkage""... $ac_c" 1>&6 -echo "configure:4752: checking for __builtin_fabsf linkage" >&5 +echo "configure:4802: checking for __builtin_fabsf linkage" >&5 if test x${glibcpp_cv_func___builtin_fabsf_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fabsf_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_fabsf(0); ; return 0; } EOF -if { (eval echo configure:4766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4816: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_fabsf_link=yes else @@ -4788,7 +4838,7 @@ EOF echo $ac_n "checking for __builtin_fabs declaration""... $ac_c" 1>&6 -echo "configure:4792: checking for __builtin_fabs declaration" >&5 +echo "configure:4842: checking for __builtin_fabs declaration" >&5 if test x${glibcpp_cv_func___builtin_fabs_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fabs_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4803,14 +4853,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_fabs(0); ; return 0; } EOF -if { (eval echo configure:4814: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4864: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_fabs_use=yes else @@ -4834,21 +4884,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_fabs_use" 1>&6 if test x$glibcpp_cv_func___builtin_fabs_use = x"yes"; then echo $ac_n "checking for __builtin_fabs linkage""... $ac_c" 1>&6 -echo "configure:4838: checking for __builtin_fabs linkage" >&5 +echo "configure:4888: checking for __builtin_fabs linkage" >&5 if test x${glibcpp_cv_func___builtin_fabs_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fabs_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_fabs(0); ; return 0; } EOF -if { (eval echo configure:4852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_fabs_link=yes else @@ -4874,7 +4924,7 @@ EOF echo $ac_n "checking for __builtin_fabsl declaration""... $ac_c" 1>&6 -echo "configure:4878: checking for __builtin_fabsl declaration" >&5 +echo "configure:4928: checking for __builtin_fabsl declaration" >&5 if test x${glibcpp_cv_func___builtin_fabsl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fabsl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4889,14 +4939,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_fabsl(0); ; return 0; } EOF -if { (eval echo configure:4900: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4950: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_fabsl_use=yes else @@ -4920,21 +4970,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_fabsl_use" 1>&6 if test x$glibcpp_cv_func___builtin_fabsl_use = x"yes"; then echo $ac_n "checking for __builtin_fabsl linkage""... $ac_c" 1>&6 -echo "configure:4924: checking for __builtin_fabsl linkage" >&5 +echo "configure:4974: checking for __builtin_fabsl linkage" >&5 if test x${glibcpp_cv_func___builtin_fabsl_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fabsl_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_fabsl(0); ; return 0; } EOF -if { (eval echo configure:4938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_fabsl_link=yes else @@ -4960,7 +5010,7 @@ EOF echo $ac_n "checking for __builtin_labs declaration""... $ac_c" 1>&6 -echo "configure:4964: checking for __builtin_labs declaration" >&5 +echo "configure:5014: checking for __builtin_labs declaration" >&5 if test x${glibcpp_cv_func___builtin_labs_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_labs_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4975,14 +5025,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_labs(0); ; return 0; } EOF -if { (eval echo configure:4986: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_labs_use=yes else @@ -5006,21 +5056,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_labs_use" 1>&6 if test x$glibcpp_cv_func___builtin_labs_use = x"yes"; then echo $ac_n "checking for __builtin_labs linkage""... $ac_c" 1>&6 -echo "configure:5010: checking for __builtin_labs linkage" >&5 +echo "configure:5060: checking for __builtin_labs linkage" >&5 if test x${glibcpp_cv_func___builtin_labs_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_labs_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_labs(0); ; return 0; } EOF -if { (eval echo configure:5024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_labs_link=yes else @@ -5047,7 +5097,7 @@ EOF echo $ac_n "checking for __builtin_sqrtf declaration""... $ac_c" 1>&6 -echo "configure:5051: checking for __builtin_sqrtf declaration" >&5 +echo "configure:5101: checking for __builtin_sqrtf declaration" >&5 if test x${glibcpp_cv_func___builtin_sqrtf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sqrtf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5062,14 +5112,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_sqrtf(0); ; return 0; } EOF -if { (eval echo configure:5073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5123: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_sqrtf_use=yes else @@ -5093,21 +5143,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_sqrtf_use" 1>&6 if test x$glibcpp_cv_func___builtin_sqrtf_use = x"yes"; then echo $ac_n "checking for __builtin_sqrtf linkage""... $ac_c" 1>&6 -echo "configure:5097: checking for __builtin_sqrtf linkage" >&5 +echo "configure:5147: checking for __builtin_sqrtf linkage" >&5 if test x${glibcpp_cv_func___builtin_sqrtf_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sqrtf_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_sqrtf(0); ; return 0; } EOF -if { (eval echo configure:5111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5161: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_sqrtf_link=yes else @@ -5133,7 +5183,7 @@ EOF echo $ac_n "checking for __builtin_fsqrt declaration""... $ac_c" 1>&6 -echo "configure:5137: checking for __builtin_fsqrt declaration" >&5 +echo "configure:5187: checking for __builtin_fsqrt declaration" >&5 if test x${glibcpp_cv_func___builtin_fsqrt_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fsqrt_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5148,14 +5198,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_fsqrt(0); ; return 0; } EOF -if { (eval echo configure:5159: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5209: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_fsqrt_use=yes else @@ -5179,21 +5229,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_fsqrt_use" 1>&6 if test x$glibcpp_cv_func___builtin_fsqrt_use = x"yes"; then echo $ac_n "checking for __builtin_fsqrt linkage""... $ac_c" 1>&6 -echo "configure:5183: checking for __builtin_fsqrt linkage" >&5 +echo "configure:5233: checking for __builtin_fsqrt linkage" >&5 if test x${glibcpp_cv_func___builtin_fsqrt_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_fsqrt_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_fsqrt(0); ; return 0; } EOF -if { (eval echo configure:5197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5247: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_fsqrt_link=yes else @@ -5219,7 +5269,7 @@ EOF echo $ac_n "checking for __builtin_sqrtl declaration""... $ac_c" 1>&6 -echo "configure:5223: checking for __builtin_sqrtl declaration" >&5 +echo "configure:5273: checking for __builtin_sqrtl declaration" >&5 if test x${glibcpp_cv_func___builtin_sqrtl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sqrtl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5234,14 +5284,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_sqrtl(0); ; return 0; } EOF -if { (eval echo configure:5245: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_sqrtl_use=yes else @@ -5265,21 +5315,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_sqrtl_use" 1>&6 if test x$glibcpp_cv_func___builtin_sqrtl_use = x"yes"; then echo $ac_n "checking for __builtin_sqrtl linkage""... $ac_c" 1>&6 -echo "configure:5269: checking for __builtin_sqrtl linkage" >&5 +echo "configure:5319: checking for __builtin_sqrtl linkage" >&5 if test x${glibcpp_cv_func___builtin_sqrtl_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sqrtl_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_sqrtl(0); ; return 0; } EOF -if { (eval echo configure:5283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_sqrtl_link=yes else @@ -5306,7 +5356,7 @@ EOF echo $ac_n "checking for __builtin_sinf declaration""... $ac_c" 1>&6 -echo "configure:5310: checking for __builtin_sinf declaration" >&5 +echo "configure:5360: checking for __builtin_sinf declaration" >&5 if test x${glibcpp_cv_func___builtin_sinf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sinf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5321,14 +5371,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_sinf(0); ; return 0; } EOF -if { (eval echo configure:5332: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5382: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_sinf_use=yes else @@ -5352,21 +5402,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_sinf_use" 1>&6 if test x$glibcpp_cv_func___builtin_sinf_use = x"yes"; then echo $ac_n "checking for __builtin_sinf linkage""... $ac_c" 1>&6 -echo "configure:5356: checking for __builtin_sinf linkage" >&5 +echo "configure:5406: checking for __builtin_sinf linkage" >&5 if test x${glibcpp_cv_func___builtin_sinf_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sinf_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_sinf(0); ; return 0; } EOF -if { (eval echo configure:5370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_sinf_link=yes else @@ -5392,7 +5442,7 @@ EOF echo $ac_n "checking for __builtin_sin declaration""... $ac_c" 1>&6 -echo "configure:5396: checking for __builtin_sin declaration" >&5 +echo "configure:5446: checking for __builtin_sin declaration" >&5 if test x${glibcpp_cv_func___builtin_sin_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sin_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5407,14 +5457,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_sin(0); ; return 0; } EOF -if { (eval echo configure:5418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5468: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_sin_use=yes else @@ -5438,21 +5488,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_sin_use" 1>&6 if test x$glibcpp_cv_func___builtin_sin_use = x"yes"; then echo $ac_n "checking for __builtin_sin linkage""... $ac_c" 1>&6 -echo "configure:5442: checking for __builtin_sin linkage" >&5 +echo "configure:5492: checking for __builtin_sin linkage" >&5 if test x${glibcpp_cv_func___builtin_sin_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sin_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_sin(0); ; return 0; } EOF -if { (eval echo configure:5456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5506: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_sin_link=yes else @@ -5478,7 +5528,7 @@ EOF echo $ac_n "checking for __builtin_sinl declaration""... $ac_c" 1>&6 -echo "configure:5482: checking for __builtin_sinl declaration" >&5 +echo "configure:5532: checking for __builtin_sinl declaration" >&5 if test x${glibcpp_cv_func___builtin_sinl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sinl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5493,14 +5543,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_sinl(0); ; return 0; } EOF -if { (eval echo configure:5504: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_sinl_use=yes else @@ -5524,21 +5574,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_sinl_use" 1>&6 if test x$glibcpp_cv_func___builtin_sinl_use = x"yes"; then echo $ac_n "checking for __builtin_sinl linkage""... $ac_c" 1>&6 -echo "configure:5528: checking for __builtin_sinl linkage" >&5 +echo "configure:5578: checking for __builtin_sinl linkage" >&5 if test x${glibcpp_cv_func___builtin_sinl_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_sinl_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_sinl(0); ; return 0; } EOF -if { (eval echo configure:5542: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_sinl_link=yes else @@ -5565,7 +5615,7 @@ EOF echo $ac_n "checking for __builtin_cosf declaration""... $ac_c" 1>&6 -echo "configure:5569: checking for __builtin_cosf declaration" >&5 +echo "configure:5619: checking for __builtin_cosf declaration" >&5 if test x${glibcpp_cv_func___builtin_cosf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_cosf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5580,14 +5630,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_cosf(0); ; return 0; } EOF -if { (eval echo configure:5591: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5641: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_cosf_use=yes else @@ -5611,21 +5661,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_cosf_use" 1>&6 if test x$glibcpp_cv_func___builtin_cosf_use = x"yes"; then echo $ac_n "checking for __builtin_cosf linkage""... $ac_c" 1>&6 -echo "configure:5615: checking for __builtin_cosf linkage" >&5 +echo "configure:5665: checking for __builtin_cosf linkage" >&5 if test x${glibcpp_cv_func___builtin_cosf_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_cosf_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_cosf(0); ; return 0; } EOF -if { (eval echo configure:5629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_cosf_link=yes else @@ -5651,7 +5701,7 @@ EOF echo $ac_n "checking for __builtin_cos declaration""... $ac_c" 1>&6 -echo "configure:5655: checking for __builtin_cos declaration" >&5 +echo "configure:5705: checking for __builtin_cos declaration" >&5 if test x${glibcpp_cv_func___builtin_cos_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_cos_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5666,14 +5716,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_cos(0); ; return 0; } EOF -if { (eval echo configure:5677: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_cos_use=yes else @@ -5697,21 +5747,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_cos_use" 1>&6 if test x$glibcpp_cv_func___builtin_cos_use = x"yes"; then echo $ac_n "checking for __builtin_cos linkage""... $ac_c" 1>&6 -echo "configure:5701: checking for __builtin_cos linkage" >&5 +echo "configure:5751: checking for __builtin_cos linkage" >&5 if test x${glibcpp_cv_func___builtin_cos_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_cos_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_cos(0); ; return 0; } EOF -if { (eval echo configure:5715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_cos_link=yes else @@ -5737,7 +5787,7 @@ EOF echo $ac_n "checking for __builtin_cosl declaration""... $ac_c" 1>&6 -echo "configure:5741: checking for __builtin_cosl declaration" >&5 +echo "configure:5791: checking for __builtin_cosl declaration" >&5 if test x${glibcpp_cv_func___builtin_cosl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_cosl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5752,14 +5802,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { __builtin_cosl(0); ; return 0; } EOF -if { (eval echo configure:5763: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5813: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func___builtin_cosl_use=yes else @@ -5783,21 +5833,21 @@ fi echo "$ac_t""$glibcpp_cv_func___builtin_cosl_use" 1>&6 if test x$glibcpp_cv_func___builtin_cosl_use = x"yes"; then echo $ac_n "checking for __builtin_cosl linkage""... $ac_c" 1>&6 -echo "configure:5787: checking for __builtin_cosl linkage" >&5 +echo "configure:5837: checking for __builtin_cosl linkage" >&5 if test x${glibcpp_cv_func___builtin_cosl_link+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func___builtin_cosl_link'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { __builtin_cosl(0); ; return 0; } EOF -if { (eval echo configure:5801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* glibcpp_cv_func___builtin_cosl_link=yes else @@ -5888,7 +5938,7 @@ EOF CXXFLAGS='-fno-builtins -D_GNU_SOURCE' echo $ac_n "checking for sin in -lm""... $ac_c" 1>&6 -echo "configure:5892: checking for sin in -lm" >&5 +echo "configure:5942: checking for sin in -lm" >&5 ac_lib_var=`echo m'_'sin | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5896,7 +5946,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5933,7 +5983,7 @@ fi echo $ac_n "checking for isinf declaration""... $ac_c" 1>&6 -echo "configure:5937: checking for isinf declaration" >&5 +echo "configure:5987: checking for isinf declaration" >&5 if test x${glibcpp_cv_func_isinf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_isinf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5948,7 +5998,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -5959,7 +6009,7 @@ int main() { isinf(0); ; return 0; } EOF -if { (eval echo configure:5963: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6013: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_isinf_use=yes else @@ -5986,12 +6036,12 @@ fi for ac_func in isinf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5990: checking for $ac_func" >&5 +echo "configure:6040: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6041,7 +6091,7 @@ done else echo $ac_n "checking for _isinf declaration""... $ac_c" 1>&6 -echo "configure:6045: checking for _isinf declaration" >&5 +echo "configure:6095: checking for _isinf declaration" >&5 if test x${glibcpp_cv_func__isinf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__isinf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6056,7 +6106,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -6067,7 +6117,7 @@ int main() { _isinf(0); ; return 0; } EOF -if { (eval echo configure:6071: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6121: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__isinf_use=yes else @@ -6094,12 +6144,12 @@ fi for ac_func in _isinf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6098: checking for $ac_func" >&5 +echo "configure:6148: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6152,7 +6202,7 @@ done echo $ac_n "checking for isnan declaration""... $ac_c" 1>&6 -echo "configure:6156: checking for isnan declaration" >&5 +echo "configure:6206: checking for isnan declaration" >&5 if test x${glibcpp_cv_func_isnan_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_isnan_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6167,7 +6217,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -6178,7 +6228,7 @@ int main() { isnan(0); ; return 0; } EOF -if { (eval echo configure:6182: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_isnan_use=yes else @@ -6205,12 +6255,12 @@ fi for ac_func in isnan do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6209: checking for $ac_func" >&5 +echo "configure:6259: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6260,7 +6310,7 @@ done else echo $ac_n "checking for _isnan declaration""... $ac_c" 1>&6 -echo "configure:6264: checking for _isnan declaration" >&5 +echo "configure:6314: checking for _isnan declaration" >&5 if test x${glibcpp_cv_func__isnan_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__isnan_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6275,7 +6325,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -6286,7 +6336,7 @@ int main() { _isnan(0); ; return 0; } EOF -if { (eval echo configure:6290: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__isnan_use=yes else @@ -6313,12 +6363,12 @@ fi for ac_func in _isnan do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6317: checking for $ac_func" >&5 +echo "configure:6367: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6395: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6371,7 +6421,7 @@ done echo $ac_n "checking for finite declaration""... $ac_c" 1>&6 -echo "configure:6375: checking for finite declaration" >&5 +echo "configure:6425: checking for finite declaration" >&5 if test x${glibcpp_cv_func_finite_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_finite_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6386,7 +6436,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -6397,7 +6447,7 @@ int main() { finite(0); ; return 0; } EOF -if { (eval echo configure:6401: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6451: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_finite_use=yes else @@ -6424,12 +6474,12 @@ fi for ac_func in finite do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6428: checking for $ac_func" >&5 +echo "configure:6478: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6506: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6479,7 +6529,7 @@ done else echo $ac_n "checking for _finite declaration""... $ac_c" 1>&6 -echo "configure:6483: checking for _finite declaration" >&5 +echo "configure:6533: checking for _finite declaration" >&5 if test x${glibcpp_cv_func__finite_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__finite_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6494,7 +6544,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -6505,7 +6555,7 @@ int main() { _finite(0); ; return 0; } EOF -if { (eval echo configure:6509: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6559: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__finite_use=yes else @@ -6532,12 +6582,12 @@ fi for ac_func in _finite do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6536: checking for $ac_func" >&5 +echo "configure:6586: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6590,7 +6640,7 @@ done echo $ac_n "checking for copysign declaration""... $ac_c" 1>&6 -echo "configure:6594: checking for copysign declaration" >&5 +echo "configure:6644: checking for copysign declaration" >&5 if test x${glibcpp_cv_func_copysign_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_copysign_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6605,14 +6655,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { copysign(0, 0); ; return 0; } EOF -if { (eval echo configure:6616: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6666: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_copysign_use=yes else @@ -6639,12 +6689,12 @@ fi for ac_func in copysign do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6643: checking for $ac_func" >&5 +echo "configure:6693: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6694,7 +6744,7 @@ done else echo $ac_n "checking for _copysign declaration""... $ac_c" 1>&6 -echo "configure:6698: checking for _copysign declaration" >&5 +echo "configure:6748: checking for _copysign declaration" >&5 if test x${glibcpp_cv_func__copysign_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__copysign_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6709,14 +6759,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _copysign(0, 0); ; return 0; } EOF -if { (eval echo configure:6720: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__copysign_use=yes else @@ -6743,12 +6793,12 @@ fi for ac_func in _copysign do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6747: checking for $ac_func" >&5 +echo "configure:6797: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6801,7 +6851,7 @@ done echo $ac_n "checking for sincos declaration""... $ac_c" 1>&6 -echo "configure:6805: checking for sincos declaration" >&5 +echo "configure:6855: checking for sincos declaration" >&5 if test x${glibcpp_cv_func_sincos_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_sincos_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6816,14 +6866,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { sincos(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:6827: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6877: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_sincos_use=yes else @@ -6850,12 +6900,12 @@ fi for ac_func in sincos do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6854: checking for $ac_func" >&5 +echo "configure:6904: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6905,7 +6955,7 @@ done else echo $ac_n "checking for _sincos declaration""... $ac_c" 1>&6 -echo "configure:6909: checking for _sincos declaration" >&5 +echo "configure:6959: checking for _sincos declaration" >&5 if test x${glibcpp_cv_func__sincos_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__sincos_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6920,14 +6970,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _sincos(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:6931: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6981: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__sincos_use=yes else @@ -6954,12 +7004,12 @@ fi for ac_func in _sincos do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6958: checking for $ac_func" >&5 +echo "configure:7008: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7012,7 +7062,7 @@ done echo $ac_n "checking for fpclass declaration""... $ac_c" 1>&6 -echo "configure:7016: checking for fpclass declaration" >&5 +echo "configure:7066: checking for fpclass declaration" >&5 if test x${glibcpp_cv_func_fpclass_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_fpclass_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7027,7 +7077,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7038,7 +7088,7 @@ int main() { fpclass(0); ; return 0; } EOF -if { (eval echo configure:7042: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7092: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_fpclass_use=yes else @@ -7065,12 +7115,12 @@ fi for ac_func in fpclass do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7069: checking for $ac_func" >&5 +echo "configure:7119: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7120,7 +7170,7 @@ done else echo $ac_n "checking for _fpclass declaration""... $ac_c" 1>&6 -echo "configure:7124: checking for _fpclass declaration" >&5 +echo "configure:7174: checking for _fpclass declaration" >&5 if test x${glibcpp_cv_func__fpclass_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__fpclass_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7135,7 +7185,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7146,7 +7196,7 @@ int main() { _fpclass(0); ; return 0; } EOF -if { (eval echo configure:7150: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__fpclass_use=yes else @@ -7173,12 +7223,12 @@ fi for ac_func in _fpclass do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7177: checking for $ac_func" >&5 +echo "configure:7227: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7231,7 +7281,7 @@ done echo $ac_n "checking for qfpclass declaration""... $ac_c" 1>&6 -echo "configure:7235: checking for qfpclass declaration" >&5 +echo "configure:7285: checking for qfpclass declaration" >&5 if test x${glibcpp_cv_func_qfpclass_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_qfpclass_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7246,7 +7296,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7257,7 +7307,7 @@ int main() { qfpclass(0); ; return 0; } EOF -if { (eval echo configure:7261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_qfpclass_use=yes else @@ -7284,12 +7334,12 @@ fi for ac_func in qfpclass do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7288: checking for $ac_func" >&5 +echo "configure:7338: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7339,7 +7389,7 @@ done else echo $ac_n "checking for _qfpclass declaration""... $ac_c" 1>&6 -echo "configure:7343: checking for _qfpclass declaration" >&5 +echo "configure:7393: checking for _qfpclass declaration" >&5 if test x${glibcpp_cv_func__qfpclass_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__qfpclass_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7354,7 +7404,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7365,7 +7415,7 @@ int main() { _qfpclass(0); ; return 0; } EOF -if { (eval echo configure:7369: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7419: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__qfpclass_use=yes else @@ -7392,12 +7442,12 @@ fi for ac_func in _qfpclass do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7396: checking for $ac_func" >&5 +echo "configure:7446: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7450,7 +7500,7 @@ done echo $ac_n "checking for float trig functions""... $ac_c" 1>&6 -echo "configure:7454: checking for float trig functions" >&5 +echo "configure:7504: checking for float trig functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func_float_trig_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7464,7 +7514,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { @@ -7473,7 +7523,7 @@ int main() { coshf sinhf tanhf; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:7477: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7527: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_float_trig_use=yes else @@ -7499,12 +7549,12 @@ fi coshf sinhf tanhf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7503: checking for $ac_func" >&5 +echo "configure:7553: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7555,7 +7605,7 @@ done echo $ac_n "checking for float round functions""... $ac_c" 1>&6 -echo "configure:7559: checking for float round functions" >&5 +echo "configure:7609: checking for float round functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func_float_round_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7569,14 +7619,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { `for x in ceilf floorf; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:7580: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7630: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_float_round_use=yes else @@ -7600,12 +7650,12 @@ fi for ac_func in ceilf floorf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7604: checking for $ac_func" >&5 +echo "configure:7654: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7657,7 +7707,7 @@ done echo $ac_n "checking for isnanf declaration""... $ac_c" 1>&6 -echo "configure:7661: checking for isnanf declaration" >&5 +echo "configure:7711: checking for isnanf declaration" >&5 if test x${glibcpp_cv_func_isnanf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_isnanf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7672,7 +7722,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7683,7 +7733,7 @@ int main() { isnanf(0); ; return 0; } EOF -if { (eval echo configure:7687: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7737: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_isnanf_use=yes else @@ -7710,12 +7760,12 @@ fi for ac_func in isnanf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7714: checking for $ac_func" >&5 +echo "configure:7764: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7765,7 +7815,7 @@ done else echo $ac_n "checking for _isnanf declaration""... $ac_c" 1>&6 -echo "configure:7769: checking for _isnanf declaration" >&5 +echo "configure:7819: checking for _isnanf declaration" >&5 if test x${glibcpp_cv_func__isnanf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__isnanf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7780,7 +7830,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7791,7 +7841,7 @@ int main() { _isnanf(0); ; return 0; } EOF -if { (eval echo configure:7795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7845: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__isnanf_use=yes else @@ -7818,12 +7868,12 @@ fi for ac_func in _isnanf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7822: checking for $ac_func" >&5 +echo "configure:7872: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7876,7 +7926,7 @@ done echo $ac_n "checking for isinff declaration""... $ac_c" 1>&6 -echo "configure:7880: checking for isinff declaration" >&5 +echo "configure:7930: checking for isinff declaration" >&5 if test x${glibcpp_cv_func_isinff_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_isinff_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7891,7 +7941,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -7902,7 +7952,7 @@ int main() { isinff(0); ; return 0; } EOF -if { (eval echo configure:7906: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7956: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_isinff_use=yes else @@ -7929,12 +7979,12 @@ fi for ac_func in isinff do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7933: checking for $ac_func" >&5 +echo "configure:7983: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8011: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -7984,7 +8034,7 @@ done else echo $ac_n "checking for _isinff declaration""... $ac_c" 1>&6 -echo "configure:7988: checking for _isinff declaration" >&5 +echo "configure:8038: checking for _isinff declaration" >&5 if test x${glibcpp_cv_func__isinff_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__isinff_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7999,7 +8049,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -8010,7 +8060,7 @@ int main() { _isinff(0); ; return 0; } EOF -if { (eval echo configure:8014: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8064: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__isinff_use=yes else @@ -8037,12 +8087,12 @@ fi for ac_func in _isinff do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8041: checking for $ac_func" >&5 +echo "configure:8091: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8095,7 +8145,7 @@ done echo $ac_n "checking for fabsf declaration""... $ac_c" 1>&6 -echo "configure:8099: checking for fabsf declaration" >&5 +echo "configure:8149: checking for fabsf declaration" >&5 if test x${glibcpp_cv_func_fabsf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_fabsf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8110,7 +8160,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -8121,7 +8171,7 @@ int main() { fabsf(0); ; return 0; } EOF -if { (eval echo configure:8125: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8175: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_fabsf_use=yes else @@ -8148,12 +8198,12 @@ fi for ac_func in fabsf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8152: checking for $ac_func" >&5 +echo "configure:8202: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8203,7 +8253,7 @@ done else echo $ac_n "checking for _fabsf declaration""... $ac_c" 1>&6 -echo "configure:8207: checking for _fabsf declaration" >&5 +echo "configure:8257: checking for _fabsf declaration" >&5 if test x${glibcpp_cv_func__fabsf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__fabsf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8218,7 +8268,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -8229,7 +8279,7 @@ int main() { _fabsf(0); ; return 0; } EOF -if { (eval echo configure:8233: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8283: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__fabsf_use=yes else @@ -8256,12 +8306,12 @@ fi for ac_func in _fabsf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8260: checking for $ac_func" >&5 +echo "configure:8310: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8314,7 +8364,7 @@ done echo $ac_n "checking for fmodf declaration""... $ac_c" 1>&6 -echo "configure:8318: checking for fmodf declaration" >&5 +echo "configure:8368: checking for fmodf declaration" >&5 if test x${glibcpp_cv_func_fmodf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_fmodf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8329,14 +8379,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { fmodf(0, 0); ; return 0; } EOF -if { (eval echo configure:8340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_fmodf_use=yes else @@ -8363,12 +8413,12 @@ fi for ac_func in fmodf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8367: checking for $ac_func" >&5 +echo "configure:8417: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8418,7 +8468,7 @@ done else echo $ac_n "checking for _fmodf declaration""... $ac_c" 1>&6 -echo "configure:8422: checking for _fmodf declaration" >&5 +echo "configure:8472: checking for _fmodf declaration" >&5 if test x${glibcpp_cv_func__fmodf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__fmodf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8433,14 +8483,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _fmodf(0, 0); ; return 0; } EOF -if { (eval echo configure:8444: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8494: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__fmodf_use=yes else @@ -8467,12 +8517,12 @@ fi for ac_func in _fmodf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8471: checking for $ac_func" >&5 +echo "configure:8521: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8525,7 +8575,7 @@ done echo $ac_n "checking for frexpf declaration""... $ac_c" 1>&6 -echo "configure:8529: checking for frexpf declaration" >&5 +echo "configure:8579: checking for frexpf declaration" >&5 if test x${glibcpp_cv_func_frexpf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_frexpf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8540,14 +8590,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { frexpf(0, 0); ; return 0; } EOF -if { (eval echo configure:8551: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8601: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_frexpf_use=yes else @@ -8574,12 +8624,12 @@ fi for ac_func in frexpf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8578: checking for $ac_func" >&5 +echo "configure:8628: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8629,7 +8679,7 @@ done else echo $ac_n "checking for _frexpf declaration""... $ac_c" 1>&6 -echo "configure:8633: checking for _frexpf declaration" >&5 +echo "configure:8683: checking for _frexpf declaration" >&5 if test x${glibcpp_cv_func__frexpf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__frexpf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8644,14 +8694,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _frexpf(0, 0); ; return 0; } EOF -if { (eval echo configure:8655: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8705: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__frexpf_use=yes else @@ -8678,12 +8728,12 @@ fi for ac_func in _frexpf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8682: checking for $ac_func" >&5 +echo "configure:8732: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8736,7 +8786,7 @@ done echo $ac_n "checking for ldexpf declaration""... $ac_c" 1>&6 -echo "configure:8740: checking for ldexpf declaration" >&5 +echo "configure:8790: checking for ldexpf declaration" >&5 if test x${glibcpp_cv_func_ldexpf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_ldexpf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8751,14 +8801,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { ldexpf(0, 0); ; return 0; } EOF -if { (eval echo configure:8762: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8812: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_ldexpf_use=yes else @@ -8785,12 +8835,12 @@ fi for ac_func in ldexpf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8789: checking for $ac_func" >&5 +echo "configure:8839: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8840,7 +8890,7 @@ done else echo $ac_n "checking for _ldexpf declaration""... $ac_c" 1>&6 -echo "configure:8844: checking for _ldexpf declaration" >&5 +echo "configure:8894: checking for _ldexpf declaration" >&5 if test x${glibcpp_cv_func__ldexpf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__ldexpf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8855,14 +8905,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _ldexpf(0, 0); ; return 0; } EOF -if { (eval echo configure:8866: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8916: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__ldexpf_use=yes else @@ -8889,12 +8939,12 @@ fi for ac_func in _ldexpf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8893: checking for $ac_func" >&5 +echo "configure:8943: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8947,7 +8997,7 @@ done echo $ac_n "checking for logf declaration""... $ac_c" 1>&6 -echo "configure:8951: checking for logf declaration" >&5 +echo "configure:9001: checking for logf declaration" >&5 if test x${glibcpp_cv_func_logf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_logf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8962,7 +9012,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -8973,7 +9023,7 @@ int main() { logf(0); ; return 0; } EOF -if { (eval echo configure:8977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9027: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_logf_use=yes else @@ -9000,12 +9050,12 @@ fi for ac_func in logf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9004: checking for $ac_func" >&5 +echo "configure:9054: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9055,7 +9105,7 @@ done else echo $ac_n "checking for _logf declaration""... $ac_c" 1>&6 -echo "configure:9059: checking for _logf declaration" >&5 +echo "configure:9109: checking for _logf declaration" >&5 if test x${glibcpp_cv_func__logf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__logf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9070,7 +9120,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -9081,7 +9131,7 @@ int main() { _logf(0); ; return 0; } EOF -if { (eval echo configure:9085: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9135: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__logf_use=yes else @@ -9108,12 +9158,12 @@ fi for ac_func in _logf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9112: checking for $ac_func" >&5 +echo "configure:9162: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9166,7 +9216,7 @@ done echo $ac_n "checking for log10f declaration""... $ac_c" 1>&6 -echo "configure:9170: checking for log10f declaration" >&5 +echo "configure:9220: checking for log10f declaration" >&5 if test x${glibcpp_cv_func_log10f_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_log10f_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9181,7 +9231,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -9192,7 +9242,7 @@ int main() { log10f(0); ; return 0; } EOF -if { (eval echo configure:9196: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_log10f_use=yes else @@ -9219,12 +9269,12 @@ fi for ac_func in log10f do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9223: checking for $ac_func" >&5 +echo "configure:9273: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9274,7 +9324,7 @@ done else echo $ac_n "checking for _log10f declaration""... $ac_c" 1>&6 -echo "configure:9278: checking for _log10f declaration" >&5 +echo "configure:9328: checking for _log10f declaration" >&5 if test x${glibcpp_cv_func__log10f_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__log10f_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9289,7 +9339,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -9300,7 +9350,7 @@ int main() { _log10f(0); ; return 0; } EOF -if { (eval echo configure:9304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9354: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__log10f_use=yes else @@ -9327,12 +9377,12 @@ fi for ac_func in _log10f do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9331: checking for $ac_func" >&5 +echo "configure:9381: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9385,7 +9435,7 @@ done echo $ac_n "checking for modff declaration""... $ac_c" 1>&6 -echo "configure:9389: checking for modff declaration" >&5 +echo "configure:9439: checking for modff declaration" >&5 if test x${glibcpp_cv_func_modff_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_modff_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9400,14 +9450,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { modff(0, 0); ; return 0; } EOF -if { (eval echo configure:9411: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9461: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_modff_use=yes else @@ -9434,12 +9484,12 @@ fi for ac_func in modff do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9438: checking for $ac_func" >&5 +echo "configure:9488: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9489,7 +9539,7 @@ done else echo $ac_n "checking for _modff declaration""... $ac_c" 1>&6 -echo "configure:9493: checking for _modff declaration" >&5 +echo "configure:9543: checking for _modff declaration" >&5 if test x${glibcpp_cv_func__modff_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__modff_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9504,14 +9554,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _modff(0, 0); ; return 0; } EOF -if { (eval echo configure:9515: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9565: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__modff_use=yes else @@ -9538,12 +9588,12 @@ fi for ac_func in _modff do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9542: checking for $ac_func" >&5 +echo "configure:9592: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9596,7 +9646,7 @@ done echo $ac_n "checking for powf declaration""... $ac_c" 1>&6 -echo "configure:9600: checking for powf declaration" >&5 +echo "configure:9650: checking for powf declaration" >&5 if test x${glibcpp_cv_func_powf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_powf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9611,14 +9661,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { powf(0, 0); ; return 0; } EOF -if { (eval echo configure:9622: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9672: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_powf_use=yes else @@ -9645,12 +9695,12 @@ fi for ac_func in powf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9649: checking for $ac_func" >&5 +echo "configure:9699: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9700,7 +9750,7 @@ done else echo $ac_n "checking for _powf declaration""... $ac_c" 1>&6 -echo "configure:9704: checking for _powf declaration" >&5 +echo "configure:9754: checking for _powf declaration" >&5 if test x${glibcpp_cv_func__powf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__powf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9715,14 +9765,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _powf(0, 0); ; return 0; } EOF -if { (eval echo configure:9726: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9776: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__powf_use=yes else @@ -9749,12 +9799,12 @@ fi for ac_func in _powf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9753: checking for $ac_func" >&5 +echo "configure:9803: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9807,7 +9857,7 @@ done echo $ac_n "checking for sqrtf declaration""... $ac_c" 1>&6 -echo "configure:9811: checking for sqrtf declaration" >&5 +echo "configure:9861: checking for sqrtf declaration" >&5 if test x${glibcpp_cv_func_sqrtf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_sqrtf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9822,7 +9872,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -9833,7 +9883,7 @@ int main() { sqrtf(0); ; return 0; } EOF -if { (eval echo configure:9837: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9887: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_sqrtf_use=yes else @@ -9860,12 +9910,12 @@ fi for ac_func in sqrtf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9864: checking for $ac_func" >&5 +echo "configure:9914: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -9915,7 +9965,7 @@ done else echo $ac_n "checking for _sqrtf declaration""... $ac_c" 1>&6 -echo "configure:9919: checking for _sqrtf declaration" >&5 +echo "configure:9969: checking for _sqrtf declaration" >&5 if test x${glibcpp_cv_func__sqrtf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__sqrtf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9930,7 +9980,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -9941,7 +9991,7 @@ int main() { _sqrtf(0); ; return 0; } EOF -if { (eval echo configure:9945: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9995: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__sqrtf_use=yes else @@ -9968,12 +10018,12 @@ fi for ac_func in _sqrtf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:9972: checking for $ac_func" >&5 +echo "configure:10022: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10026,7 +10076,7 @@ done echo $ac_n "checking for sincosf declaration""... $ac_c" 1>&6 -echo "configure:10030: checking for sincosf declaration" >&5 +echo "configure:10080: checking for sincosf declaration" >&5 if test x${glibcpp_cv_func_sincosf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_sincosf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10041,14 +10091,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { sincosf(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:10052: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10102: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_sincosf_use=yes else @@ -10075,12 +10125,12 @@ fi for ac_func in sincosf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10079: checking for $ac_func" >&5 +echo "configure:10129: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10130,7 +10180,7 @@ done else echo $ac_n "checking for _sincosf declaration""... $ac_c" 1>&6 -echo "configure:10134: checking for _sincosf declaration" >&5 +echo "configure:10184: checking for _sincosf declaration" >&5 if test x${glibcpp_cv_func__sincosf_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__sincosf_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10145,14 +10195,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _sincosf(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:10156: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__sincosf_use=yes else @@ -10179,12 +10229,12 @@ fi for ac_func in _sincosf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10183: checking for $ac_func" >&5 +echo "configure:10233: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10261: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10237,7 +10287,7 @@ done echo $ac_n "checking for finitef declaration""... $ac_c" 1>&6 -echo "configure:10241: checking for finitef declaration" >&5 +echo "configure:10291: checking for finitef declaration" >&5 if test x${glibcpp_cv_func_finitef_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_finitef_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10252,7 +10302,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -10263,7 +10313,7 @@ int main() { finitef(0); ; return 0; } EOF -if { (eval echo configure:10267: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_finitef_use=yes else @@ -10290,12 +10340,12 @@ fi for ac_func in finitef do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10294: checking for $ac_func" >&5 +echo "configure:10344: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10345,7 +10395,7 @@ done else echo $ac_n "checking for _finitef declaration""... $ac_c" 1>&6 -echo "configure:10349: checking for _finitef declaration" >&5 +echo "configure:10399: checking for _finitef declaration" >&5 if test x${glibcpp_cv_func__finitef_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__finitef_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10360,7 +10410,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -10371,7 +10421,7 @@ int main() { _finitef(0); ; return 0; } EOF -if { (eval echo configure:10375: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10425: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__finitef_use=yes else @@ -10398,12 +10448,12 @@ fi for ac_func in _finitef do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10402: checking for $ac_func" >&5 +echo "configure:10452: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10456,7 +10506,7 @@ done echo $ac_n "checking for long double trig functions""... $ac_c" 1>&6 -echo "configure:10460: checking for long double trig functions" >&5 +echo "configure:10510: checking for long double trig functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func_long_double_trig_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10470,7 +10520,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { @@ -10479,7 +10529,7 @@ int main() { coshl sinhl tanhl; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:10483: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10533: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_long_double_trig_use=yes else @@ -10505,12 +10555,12 @@ fi coshl sinhl tanhl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10509: checking for $ac_func" >&5 +echo "configure:10559: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10561,7 +10611,7 @@ done echo $ac_n "checking for long double round functions""... $ac_c" 1>&6 -echo "configure:10565: checking for long double round functions" >&5 +echo "configure:10615: checking for long double round functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func_long_double_round_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10575,14 +10625,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { `for x in ceill floorl; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:10586: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10636: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_long_double_round_use=yes else @@ -10606,12 +10656,12 @@ fi for ac_func in ceill floorl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10610: checking for $ac_func" >&5 +echo "configure:10660: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10663,7 +10713,7 @@ done echo $ac_n "checking for isnanl declaration""... $ac_c" 1>&6 -echo "configure:10667: checking for isnanl declaration" >&5 +echo "configure:10717: checking for isnanl declaration" >&5 if test x${glibcpp_cv_func_isnanl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_isnanl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10678,7 +10728,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -10689,7 +10739,7 @@ int main() { isnanl(0); ; return 0; } EOF -if { (eval echo configure:10693: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_isnanl_use=yes else @@ -10716,12 +10766,12 @@ fi for ac_func in isnanl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10720: checking for $ac_func" >&5 +echo "configure:10770: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10771,7 +10821,7 @@ done else echo $ac_n "checking for _isnanl declaration""... $ac_c" 1>&6 -echo "configure:10775: checking for _isnanl declaration" >&5 +echo "configure:10825: checking for _isnanl declaration" >&5 if test x${glibcpp_cv_func__isnanl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__isnanl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10786,7 +10836,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -10797,7 +10847,7 @@ int main() { _isnanl(0); ; return 0; } EOF -if { (eval echo configure:10801: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10851: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__isnanl_use=yes else @@ -10824,12 +10874,12 @@ fi for ac_func in _isnanl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10828: checking for $ac_func" >&5 +echo "configure:10878: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10882,7 +10932,7 @@ done echo $ac_n "checking for isinfl declaration""... $ac_c" 1>&6 -echo "configure:10886: checking for isinfl declaration" >&5 +echo "configure:10936: checking for isinfl declaration" >&5 if test x${glibcpp_cv_func_isinfl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_isinfl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -10897,7 +10947,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -10908,7 +10958,7 @@ int main() { isinfl(0); ; return 0; } EOF -if { (eval echo configure:10912: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10962: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_isinfl_use=yes else @@ -10935,12 +10985,12 @@ fi for ac_func in isinfl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10939: checking for $ac_func" >&5 +echo "configure:10989: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10990,7 +11040,7 @@ done else echo $ac_n "checking for _isinfl declaration""... $ac_c" 1>&6 -echo "configure:10994: checking for _isinfl declaration" >&5 +echo "configure:11044: checking for _isinfl declaration" >&5 if test x${glibcpp_cv_func__isinfl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__isinfl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11005,7 +11055,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -11016,7 +11066,7 @@ int main() { _isinfl(0); ; return 0; } EOF -if { (eval echo configure:11020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11070: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__isinfl_use=yes else @@ -11043,12 +11093,12 @@ fi for ac_func in _isinfl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11047: checking for $ac_func" >&5 +echo "configure:11097: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11101,7 +11151,7 @@ done echo $ac_n "checking for copysignl declaration""... $ac_c" 1>&6 -echo "configure:11105: checking for copysignl declaration" >&5 +echo "configure:11155: checking for copysignl declaration" >&5 if test x${glibcpp_cv_func_copysignl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_copysignl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11116,14 +11166,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { copysignl(0, 0); ; return 0; } EOF -if { (eval echo configure:11127: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11177: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_copysignl_use=yes else @@ -11150,12 +11200,12 @@ fi for ac_func in copysignl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11154: checking for $ac_func" >&5 +echo "configure:11204: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11205,7 +11255,7 @@ done else echo $ac_n "checking for _copysignl declaration""... $ac_c" 1>&6 -echo "configure:11209: checking for _copysignl declaration" >&5 +echo "configure:11259: checking for _copysignl declaration" >&5 if test x${glibcpp_cv_func__copysignl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__copysignl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11220,14 +11270,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _copysignl(0, 0); ; return 0; } EOF -if { (eval echo configure:11231: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11281: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__copysignl_use=yes else @@ -11254,12 +11304,12 @@ fi for ac_func in _copysignl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11258: checking for $ac_func" >&5 +echo "configure:11308: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11312,7 +11362,7 @@ done echo $ac_n "checking for atan2l declaration""... $ac_c" 1>&6 -echo "configure:11316: checking for atan2l declaration" >&5 +echo "configure:11366: checking for atan2l declaration" >&5 if test x${glibcpp_cv_func_atan2l_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_atan2l_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11327,14 +11377,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { atan2l(0, 0); ; return 0; } EOF -if { (eval echo configure:11338: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_atan2l_use=yes else @@ -11361,12 +11411,12 @@ fi for ac_func in atan2l do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11365: checking for $ac_func" >&5 +echo "configure:11415: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11416,7 +11466,7 @@ done else echo $ac_n "checking for _atan2l declaration""... $ac_c" 1>&6 -echo "configure:11420: checking for _atan2l declaration" >&5 +echo "configure:11470: checking for _atan2l declaration" >&5 if test x${glibcpp_cv_func__atan2l_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__atan2l_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11431,14 +11481,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _atan2l(0, 0); ; return 0; } EOF -if { (eval echo configure:11442: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11492: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__atan2l_use=yes else @@ -11465,12 +11515,12 @@ fi for ac_func in _atan2l do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11469: checking for $ac_func" >&5 +echo "configure:11519: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11523,7 +11573,7 @@ done echo $ac_n "checking for expl declaration""... $ac_c" 1>&6 -echo "configure:11527: checking for expl declaration" >&5 +echo "configure:11577: checking for expl declaration" >&5 if test x${glibcpp_cv_func_expl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_expl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11538,7 +11588,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -11549,7 +11599,7 @@ int main() { expl(0); ; return 0; } EOF -if { (eval echo configure:11553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11603: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_expl_use=yes else @@ -11576,12 +11626,12 @@ fi for ac_func in expl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11580: checking for $ac_func" >&5 +echo "configure:11630: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11631,7 +11681,7 @@ done else echo $ac_n "checking for _expl declaration""... $ac_c" 1>&6 -echo "configure:11635: checking for _expl declaration" >&5 +echo "configure:11685: checking for _expl declaration" >&5 if test x${glibcpp_cv_func__expl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__expl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11646,7 +11696,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -11657,7 +11707,7 @@ int main() { _expl(0); ; return 0; } EOF -if { (eval echo configure:11661: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11711: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__expl_use=yes else @@ -11684,12 +11734,12 @@ fi for ac_func in _expl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11688: checking for $ac_func" >&5 +echo "configure:11738: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11742,7 +11792,7 @@ done echo $ac_n "checking for fabsl declaration""... $ac_c" 1>&6 -echo "configure:11746: checking for fabsl declaration" >&5 +echo "configure:11796: checking for fabsl declaration" >&5 if test x${glibcpp_cv_func_fabsl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_fabsl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11757,7 +11807,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -11768,7 +11818,7 @@ int main() { fabsl(0); ; return 0; } EOF -if { (eval echo configure:11772: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_fabsl_use=yes else @@ -11795,12 +11845,12 @@ fi for ac_func in fabsl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11799: checking for $ac_func" >&5 +echo "configure:11849: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11850,7 +11900,7 @@ done else echo $ac_n "checking for _fabsl declaration""... $ac_c" 1>&6 -echo "configure:11854: checking for _fabsl declaration" >&5 +echo "configure:11904: checking for _fabsl declaration" >&5 if test x${glibcpp_cv_func__fabsl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__fabsl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11865,7 +11915,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -11876,7 +11926,7 @@ int main() { _fabsl(0); ; return 0; } EOF -if { (eval echo configure:11880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11930: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__fabsl_use=yes else @@ -11903,12 +11953,12 @@ fi for ac_func in _fabsl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11907: checking for $ac_func" >&5 +echo "configure:11957: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11961,7 +12011,7 @@ done echo $ac_n "checking for fmodl declaration""... $ac_c" 1>&6 -echo "configure:11965: checking for fmodl declaration" >&5 +echo "configure:12015: checking for fmodl declaration" >&5 if test x${glibcpp_cv_func_fmodl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_fmodl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11976,14 +12026,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { fmodl(0, 0); ; return 0; } EOF -if { (eval echo configure:11987: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_fmodl_use=yes else @@ -12010,12 +12060,12 @@ fi for ac_func in fmodl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12014: checking for $ac_func" >&5 +echo "configure:12064: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12065,7 +12115,7 @@ done else echo $ac_n "checking for _fmodl declaration""... $ac_c" 1>&6 -echo "configure:12069: checking for _fmodl declaration" >&5 +echo "configure:12119: checking for _fmodl declaration" >&5 if test x${glibcpp_cv_func__fmodl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__fmodl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12080,14 +12130,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _fmodl(0, 0); ; return 0; } EOF -if { (eval echo configure:12091: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__fmodl_use=yes else @@ -12114,12 +12164,12 @@ fi for ac_func in _fmodl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12118: checking for $ac_func" >&5 +echo "configure:12168: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12172,7 +12222,7 @@ done echo $ac_n "checking for frexpl declaration""... $ac_c" 1>&6 -echo "configure:12176: checking for frexpl declaration" >&5 +echo "configure:12226: checking for frexpl declaration" >&5 if test x${glibcpp_cv_func_frexpl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_frexpl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12187,14 +12237,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { frexpl(0, 0); ; return 0; } EOF -if { (eval echo configure:12198: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_frexpl_use=yes else @@ -12221,12 +12271,12 @@ fi for ac_func in frexpl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12225: checking for $ac_func" >&5 +echo "configure:12275: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12303: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12276,7 +12326,7 @@ done else echo $ac_n "checking for _frexpl declaration""... $ac_c" 1>&6 -echo "configure:12280: checking for _frexpl declaration" >&5 +echo "configure:12330: checking for _frexpl declaration" >&5 if test x${glibcpp_cv_func__frexpl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__frexpl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12291,14 +12341,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _frexpl(0, 0); ; return 0; } EOF -if { (eval echo configure:12302: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12352: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__frexpl_use=yes else @@ -12325,12 +12375,12 @@ fi for ac_func in _frexpl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12329: checking for $ac_func" >&5 +echo "configure:12379: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12383,7 +12433,7 @@ done echo $ac_n "checking for ldexpl declaration""... $ac_c" 1>&6 -echo "configure:12387: checking for ldexpl declaration" >&5 +echo "configure:12437: checking for ldexpl declaration" >&5 if test x${glibcpp_cv_func_ldexpl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_ldexpl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12398,14 +12448,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { ldexpl(0, 0); ; return 0; } EOF -if { (eval echo configure:12409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_ldexpl_use=yes else @@ -12432,12 +12482,12 @@ fi for ac_func in ldexpl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12436: checking for $ac_func" >&5 +echo "configure:12486: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12487,7 +12537,7 @@ done else echo $ac_n "checking for _ldexpl declaration""... $ac_c" 1>&6 -echo "configure:12491: checking for _ldexpl declaration" >&5 +echo "configure:12541: checking for _ldexpl declaration" >&5 if test x${glibcpp_cv_func__ldexpl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__ldexpl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12502,14 +12552,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _ldexpl(0, 0); ; return 0; } EOF -if { (eval echo configure:12513: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12563: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__ldexpl_use=yes else @@ -12536,12 +12586,12 @@ fi for ac_func in _ldexpl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12540: checking for $ac_func" >&5 +echo "configure:12590: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12594,7 +12644,7 @@ done echo $ac_n "checking for logl declaration""... $ac_c" 1>&6 -echo "configure:12598: checking for logl declaration" >&5 +echo "configure:12648: checking for logl declaration" >&5 if test x${glibcpp_cv_func_logl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_logl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12609,7 +12659,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -12620,7 +12670,7 @@ int main() { logl(0); ; return 0; } EOF -if { (eval echo configure:12624: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12674: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_logl_use=yes else @@ -12647,12 +12697,12 @@ fi for ac_func in logl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12651: checking for $ac_func" >&5 +echo "configure:12701: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12702,7 +12752,7 @@ done else echo $ac_n "checking for _logl declaration""... $ac_c" 1>&6 -echo "configure:12706: checking for _logl declaration" >&5 +echo "configure:12756: checking for _logl declaration" >&5 if test x${glibcpp_cv_func__logl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__logl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12717,7 +12767,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -12728,7 +12778,7 @@ int main() { _logl(0); ; return 0; } EOF -if { (eval echo configure:12732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12782: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__logl_use=yes else @@ -12755,12 +12805,12 @@ fi for ac_func in _logl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12759: checking for $ac_func" >&5 +echo "configure:12809: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12813,7 +12863,7 @@ done echo $ac_n "checking for log10l declaration""... $ac_c" 1>&6 -echo "configure:12817: checking for log10l declaration" >&5 +echo "configure:12867: checking for log10l declaration" >&5 if test x${glibcpp_cv_func_log10l_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_log10l_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12828,7 +12878,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -12839,7 +12889,7 @@ int main() { log10l(0); ; return 0; } EOF -if { (eval echo configure:12843: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12893: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_log10l_use=yes else @@ -12866,12 +12916,12 @@ fi for ac_func in log10l do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12870: checking for $ac_func" >&5 +echo "configure:12920: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12921,7 +12971,7 @@ done else echo $ac_n "checking for _log10l declaration""... $ac_c" 1>&6 -echo "configure:12925: checking for _log10l declaration" >&5 +echo "configure:12975: checking for _log10l declaration" >&5 if test x${glibcpp_cv_func__log10l_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__log10l_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -12936,7 +12986,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -12947,7 +12997,7 @@ int main() { _log10l(0); ; return 0; } EOF -if { (eval echo configure:12951: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13001: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__log10l_use=yes else @@ -12974,12 +13024,12 @@ fi for ac_func in _log10l do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12978: checking for $ac_func" >&5 +echo "configure:13028: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13056: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13032,7 +13082,7 @@ done echo $ac_n "checking for modfl declaration""... $ac_c" 1>&6 -echo "configure:13036: checking for modfl declaration" >&5 +echo "configure:13086: checking for modfl declaration" >&5 if test x${glibcpp_cv_func_modfl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_modfl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13047,14 +13097,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { modfl(0, 0); ; return 0; } EOF -if { (eval echo configure:13058: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13108: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_modfl_use=yes else @@ -13081,12 +13131,12 @@ fi for ac_func in modfl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13085: checking for $ac_func" >&5 +echo "configure:13135: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13136,7 +13186,7 @@ done else echo $ac_n "checking for _modfl declaration""... $ac_c" 1>&6 -echo "configure:13140: checking for _modfl declaration" >&5 +echo "configure:13190: checking for _modfl declaration" >&5 if test x${glibcpp_cv_func__modfl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__modfl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13151,14 +13201,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _modfl(0, 0); ; return 0; } EOF -if { (eval echo configure:13162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13212: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__modfl_use=yes else @@ -13185,12 +13235,12 @@ fi for ac_func in _modfl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13189: checking for $ac_func" >&5 +echo "configure:13239: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13267: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13243,7 +13293,7 @@ done echo $ac_n "checking for powl declaration""... $ac_c" 1>&6 -echo "configure:13247: checking for powl declaration" >&5 +echo "configure:13297: checking for powl declaration" >&5 if test x${glibcpp_cv_func_powl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_powl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13258,14 +13308,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { powl(0, 0); ; return 0; } EOF -if { (eval echo configure:13269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13319: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_powl_use=yes else @@ -13292,12 +13342,12 @@ fi for ac_func in powl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13296: checking for $ac_func" >&5 +echo "configure:13346: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13347,7 +13397,7 @@ done else echo $ac_n "checking for _powl declaration""... $ac_c" 1>&6 -echo "configure:13351: checking for _powl declaration" >&5 +echo "configure:13401: checking for _powl declaration" >&5 if test x${glibcpp_cv_func__powl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__powl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13362,14 +13412,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _powl(0, 0); ; return 0; } EOF -if { (eval echo configure:13373: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13423: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__powl_use=yes else @@ -13396,12 +13446,12 @@ fi for ac_func in _powl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13400: checking for $ac_func" >&5 +echo "configure:13450: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13478: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13454,7 +13504,7 @@ done echo $ac_n "checking for sqrtl declaration""... $ac_c" 1>&6 -echo "configure:13458: checking for sqrtl declaration" >&5 +echo "configure:13508: checking for sqrtl declaration" >&5 if test x${glibcpp_cv_func_sqrtl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_sqrtl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13469,7 +13519,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -13480,7 +13530,7 @@ int main() { sqrtl(0); ; return 0; } EOF -if { (eval echo configure:13484: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13534: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_sqrtl_use=yes else @@ -13507,12 +13557,12 @@ fi for ac_func in sqrtl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13511: checking for $ac_func" >&5 +echo "configure:13561: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13562,7 +13612,7 @@ done else echo $ac_n "checking for _sqrtl declaration""... $ac_c" 1>&6 -echo "configure:13566: checking for _sqrtl declaration" >&5 +echo "configure:13616: checking for _sqrtl declaration" >&5 if test x${glibcpp_cv_func__sqrtl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__sqrtl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13577,7 +13627,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -13588,7 +13638,7 @@ int main() { _sqrtl(0); ; return 0; } EOF -if { (eval echo configure:13592: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__sqrtl_use=yes else @@ -13615,12 +13665,12 @@ fi for ac_func in _sqrtl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13619: checking for $ac_func" >&5 +echo "configure:13669: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13673,7 +13723,7 @@ done echo $ac_n "checking for sincosl declaration""... $ac_c" 1>&6 -echo "configure:13677: checking for sincosl declaration" >&5 +echo "configure:13727: checking for sincosl declaration" >&5 if test x${glibcpp_cv_func_sincosl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_sincosl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13688,14 +13738,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { sincosl(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:13699: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13749: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_sincosl_use=yes else @@ -13722,12 +13772,12 @@ fi for ac_func in sincosl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13726: checking for $ac_func" >&5 +echo "configure:13776: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13777,7 +13827,7 @@ done else echo $ac_n "checking for _sincosl declaration""... $ac_c" 1>&6 -echo "configure:13781: checking for _sincosl declaration" >&5 +echo "configure:13831: checking for _sincosl declaration" >&5 if test x${glibcpp_cv_func__sincosl_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__sincosl_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13792,14 +13842,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { _sincosl(0, 0, 0); ; return 0; } EOF -if { (eval echo configure:13803: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13853: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__sincosl_use=yes else @@ -13826,12 +13876,12 @@ fi for ac_func in _sincosl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13830: checking for $ac_func" >&5 +echo "configure:13880: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13884,7 +13934,7 @@ done echo $ac_n "checking for finitel declaration""... $ac_c" 1>&6 -echo "configure:13888: checking for finitel declaration" >&5 +echo "configure:13938: checking for finitel declaration" >&5 if test x${glibcpp_cv_func_finitel_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_finitel_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13899,7 +13949,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -13910,7 +13960,7 @@ int main() { finitel(0); ; return 0; } EOF -if { (eval echo configure:13914: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:13964: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_finitel_use=yes else @@ -13937,12 +13987,12 @@ fi for ac_func in finitel do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:13941: checking for $ac_func" >&5 +echo "configure:13991: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -13992,7 +14042,7 @@ done else echo $ac_n "checking for _finitel declaration""... $ac_c" 1>&6 -echo "configure:13996: checking for _finitel declaration" >&5 +echo "configure:14046: checking for _finitel declaration" >&5 if test x${glibcpp_cv_func__finitel_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func__finitel_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14007,7 +14057,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < #ifdef HAVE_IEEEFP_H @@ -14018,7 +14068,7 @@ int main() { _finitel(0); ; return 0; } EOF -if { (eval echo configure:14022: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14072: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__finitel_use=yes else @@ -14045,12 +14095,12 @@ fi for ac_func in _finitel do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14049: checking for $ac_func" >&5 +echo "configure:14099: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14104,7 +14154,7 @@ done echo $ac_n "checking for _float trig functions""... $ac_c" 1>&6 -echo "configure:14108: checking for _float trig functions" >&5 +echo "configure:14158: checking for _float trig functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func__float_trig_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -14118,7 +14168,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { @@ -14127,7 +14177,7 @@ int main() { _coshf _sinhf _tanhf; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:14131: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14181: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__float_trig_use=yes else @@ -14153,12 +14203,12 @@ fi _coshf _sinhf _tanhf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14157: checking for $ac_func" >&5 +echo "configure:14207: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14209,7 +14259,7 @@ done echo $ac_n "checking for _float round functions""... $ac_c" 1>&6 -echo "configure:14213: checking for _float round functions" >&5 +echo "configure:14263: checking for _float round functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func__float_round_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -14223,14 +14273,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { `for x in _ceilf _floorf; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:14234: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__float_round_use=yes else @@ -14254,12 +14304,12 @@ fi for ac_func in _ceilf _floorf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14258: checking for $ac_func" >&5 +echo "configure:14308: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14311,7 +14361,7 @@ done echo $ac_n "checking for _long double trig functions""... $ac_c" 1>&6 -echo "configure:14315: checking for _long double trig functions" >&5 +echo "configure:14365: checking for _long double trig functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func__long_double_trig_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -14325,7 +14375,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { @@ -14334,7 +14384,7 @@ int main() { _coshl _sinhl _tanhl; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:14338: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__long_double_trig_use=yes else @@ -14360,12 +14410,12 @@ fi _coshl _sinhl _tanhl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14364: checking for $ac_func" >&5 +echo "configure:14414: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14416,7 +14466,7 @@ done echo $ac_n "checking for _long double round functions""... $ac_c" 1>&6 -echo "configure:14420: checking for _long double round functions" >&5 +echo "configure:14470: checking for _long double round functions" >&5 if eval "test \"`echo '$''{'glibcpp_cv_func__long_double_round_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -14430,14 +14480,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { `for x in _ceill _floorl; do echo "$x (0);"; done` ; return 0; } EOF -if { (eval echo configure:14441: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14491: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func__long_double_round_use=yes else @@ -14461,12 +14511,12 @@ fi for ac_func in _ceill _floorl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14465: checking for $ac_func" >&5 +echo "configure:14515: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14543: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14521,7 +14571,7 @@ done echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:14525: checking for main in -lm" >&5 +echo "configure:14575: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14529,14 +14579,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14566,12 +14616,12 @@ fi for ac_func in nan hypot hypotf atan2f expf copysignf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14570: checking for $ac_func" >&5 +echo "configure:14620: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14628,12 +14678,12 @@ done for ac_func in hypotl signbitl do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14632: checking for $ac_func" >&5 +echo "configure:14682: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -14690,7 +14740,7 @@ done echo $ac_n "checking for GNU C++ __complex__ support""... $ac_c" 1>&6 -echo "configure:14694: checking for GNU C++ __complex__ support" >&5 +echo "configure:14744: checking for GNU C++ __complex__ support" >&5 if eval "test \"`echo '$''{'glibcpp_cv_complex'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -14704,7 +14754,7 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_complex=ok else @@ -14743,7 +14793,7 @@ EOF fi echo $ac_n "checking for GNU C++ __complex__ float support""... $ac_c" 1>&6 -echo "configure:14747: checking for GNU C++ __complex__ float support" >&5 +echo "configure:14797: checking for GNU C++ __complex__ float support" >&5 if eval "test \"`echo '$''{'glibcpp_cv_float_complex'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -14776,14 +14826,14 @@ cross_compiling=$ac_cv_prog_cxx_cross }; EOB cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14837: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_float_complex=ok else @@ -14815,16 +14865,16 @@ EOF echo $ac_n "checking for mbstate_t""... $ac_c" 1>&6 -echo "configure:14819: checking for mbstate_t" >&5 +echo "configure:14869: checking for mbstate_t" >&5 cat > conftest.$ac_ext < int main() { mbstate_t teststate; ; return 0; } EOF -if { (eval echo configure:14828: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14878: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* have_mbstate_t=yes else @@ -14846,17 +14896,17 @@ EOF do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:14850: checking for $ac_hdr" >&5 +echo "configure:14900: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:14860: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:14910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -14885,17 +14935,17 @@ done ac_safe=`echo "wctype.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for wctype.h""... $ac_c" 1>&6 -echo "configure:14889: checking for wctype.h" >&5 +echo "configure:14939: checking for wctype.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:14899: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:14949: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -14922,16 +14972,16 @@ fi && test x"$enable_c_mbchar" != xno; then echo $ac_n "checking for WCHAR_MIN and WCHAR_MAX""... $ac_c" 1>&6 -echo "configure:14926: checking for WCHAR_MIN and WCHAR_MAX" >&5 +echo "configure:14976: checking for WCHAR_MIN and WCHAR_MAX" >&5 cat > conftest.$ac_ext < int main() { int i = WCHAR_MIN; int j = WCHAR_MAX; ; return 0; } EOF -if { (eval echo configure:14935: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14985: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* has_wchar_minmax=yes else @@ -14944,9 +14994,9 @@ rm -f conftest* echo "$ac_t""$has_wchar_minmax" 1>&6 echo $ac_n "checking for WEOF""... $ac_c" 1>&6 -echo "configure:14948: checking for WEOF" >&5 +echo "configure:14998: checking for WEOF" >&5 cat > conftest.$ac_ext < @@ -14955,7 +15005,7 @@ int main() { wint_t i = WEOF; ; return 0; } EOF -if { (eval echo configure:14959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:15009: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* has_weof=yes else @@ -14971,12 +15021,12 @@ rm -f conftest* wcsrtombs mbsrtowcs do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:14975: checking for $ac_func" >&5 +echo "configure:15025: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -15026,7 +15076,7 @@ done echo $ac_n "checking for ISO C99 wchar_t support""... $ac_c" 1>&6 -echo "configure:15030: checking for ISO C99 wchar_t support" >&5 +echo "configure:15080: checking for ISO C99 wchar_t support" >&5 if test x"$has_weof" = xyes && test x"$has_wchar_minmax" = xyes \ && test x"$ac_wfuncs" = xyes; then ac_isoC99_wchar_t=yes @@ -15037,17 +15087,17 @@ echo "configure:15030: checking for ISO C99 wchar_t support" >&5 ac_safe=`echo "iconv.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for iconv.h""... $ac_c" 1>&6 -echo "configure:15041: checking for iconv.h" >&5 +echo "configure:15091: checking for iconv.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15051: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:15101: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -15071,17 +15121,17 @@ fi ac_safe=`echo "langinfo.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for langinfo.h""... $ac_c" 1>&6 -echo "configure:15075: checking for langinfo.h" >&5 +echo "configure:15125: checking for langinfo.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15085: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:15135: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -15105,7 +15155,7 @@ fi echo $ac_n "checking for iconv in -liconv""... $ac_c" 1>&6 -echo "configure:15109: checking for iconv in -liconv" >&5 +echo "configure:15159: checking for iconv in -liconv" >&5 ac_lib_var=`echo iconv'_'iconv | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -15113,7 +15163,7 @@ else ac_save_LIBS="$LIBS" LIBS="-liconv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -15150,12 +15200,12 @@ fi for ac_func in iconv_open iconv_close iconv nl_langinfo do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:15154: checking for $ac_func" >&5 +echo "configure:15204: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -15208,7 +15258,7 @@ done LIBS="$ac_save_LIBS" echo $ac_n "checking for XPG2 wchar_t support""... $ac_c" 1>&6 -echo "configure:15212: checking for XPG2 wchar_t support" >&5 +echo "configure:15262: checking for XPG2 wchar_t support" >&5 if test x"$ac_has_iconv_h" = xyes && test x"$ac_has_langinfo_h" = xyes \ && test x"$ac_XPG2funcs" = xyes; then ac_XPG2_wchar_t=yes @@ -15218,7 +15268,7 @@ echo "configure:15212: checking for XPG2 wchar_t support" >&5 echo "$ac_t""$ac_XPG2_wchar_t" 1>&6 echo $ac_n "checking for enabled wchar_t specializations""... $ac_c" 1>&6 -echo "configure:15222: checking for enabled wchar_t specializations" >&5 +echo "configure:15272: checking for enabled wchar_t specializations" >&5 if test x"$ac_isoC99_wchar_t" = xyes \ && test x"$ac_XPG2_wchar_t" = xyes; then cat >> confdefs.h <<\EOF @@ -15241,12 +15291,12 @@ EOF for ac_func in strtof do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:15245: checking for $ac_func" >&5 +echo "configure:15295: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -15295,7 +15345,7 @@ done echo $ac_n "checking for strtold declaration""... $ac_c" 1>&6 -echo "configure:15299: checking for strtold declaration" >&5 +echo "configure:15349: checking for strtold declaration" >&5 if test x${glibcpp_cv_func_strtold_use+set} != xset; then if eval "test \"`echo '$''{'glibcpp_cv_func_strtold_use'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -15310,14 +15360,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext < int main() { strtold(0, 0); ; return 0; } EOF -if { (eval echo configure:15321: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:15371: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* glibcpp_cv_func_strtold_use=yes else @@ -15343,12 +15393,12 @@ fi for ac_func in strtold do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:15347: checking for $ac_func" >&5 +echo "configure:15397: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -15402,7 +15452,7 @@ done cat > conftest.$ac_ext < @@ -15411,7 +15461,7 @@ int main() { sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1); ; return 0; } EOF -if { (eval echo configure:15415: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:15465: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_SIGSETJMP 1 @@ -15427,17 +15477,17 @@ rm -f conftest* do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:15431: checking for $ac_hdr" >&5 +echo "configure:15481: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:15491: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -15466,12 +15516,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:15470: checking for $ac_func" >&5 +echo "configure:15520: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -15519,7 +15569,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:15523: checking for working mmap" >&5 +echo "configure:15573: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -15527,7 +15577,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:15721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -15775,17 +15825,17 @@ rm -f confcache ac_safe=`echo "locale.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for locale.h""... $ac_c" 1>&6 -echo "configure:15779: checking for locale.h" >&5 +echo "configure:15829: checking for locale.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15789: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:15839: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -15803,19 +15853,19 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 -echo "configure:15807: checking for LC_MESSAGES" >&5 +echo "configure:15857: checking for LC_MESSAGES" >&5 if eval "test \"`echo '$''{'ac_cv_val_LC_MESSAGES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return LC_MESSAGES ; return 0; } EOF -if { (eval echo configure:15819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_val_LC_MESSAGES=yes else @@ -15860,13 +15910,13 @@ glibcpp_toolexecdir=no glibcpp_toolexeclibdir=no echo $ac_n "checking for interface version number""... $ac_c" 1>&6 -echo "configure:15864: checking for interface version number" >&5 +echo "configure:15914: checking for interface version number" >&5 libstdcxx_interface=$INTERFACE echo "$ac_t""$libstdcxx_interface" 1>&6 # Process the option --with-gxx-include-dir= echo $ac_n "checking for --with-gxx-include-dir""... $ac_c" 1>&6 -echo "configure:15870: checking for --with-gxx-include-dir" >&5 +echo "configure:15920: checking for --with-gxx-include-dir" >&5 # Check whether --with-gxx-include-dir or --without-gxx-include-dir was given. if test "${with_gxx_include_dir+set}" = set; then withval="$with_gxx_include_dir" @@ -15890,7 +15940,7 @@ echo "$ac_t""$gxx_include_dir" 1>&6 # Process the option "--enable-version-specific-runtime-libs" echo $ac_n "checking for --enable-version-specific-runtime-libs""... $ac_c" 1>&6 -echo "configure:15894: checking for --enable-version-specific-runtime-libs" >&5 +echo "configure:15944: checking for --enable-version-specific-runtime-libs" >&5 # Check whether --enable-version-specific-runtime-libs or --disable-version-specific-runtime-libs was given. if test "${enable_version_specific_runtime_libs+set}" = set; then enableval="$enable_version_specific_runtime_libs" @@ -15930,7 +15980,7 @@ if test x"$glibcpp_toolexecdir" = x"no"; then fi echo $ac_n "checking for install location""... $ac_c" 1>&6 -echo "configure:15934: checking for install location" >&5 +echo "configure:15984: checking for install location" >&5 echo "$ac_t""$gxx_include_dir" 1>&6 diff --git a/libstdc++-v3/configure.in b/libstdc++-v3/configure.in index 544db19b174..1de7539fdfc 100644 --- a/libstdc++-v3/configure.in +++ b/libstdc++-v3/configure.in @@ -68,6 +68,7 @@ GLIBCPP_ENABLE_LONG_LONG([no]) GLIBCPP_ENABLE_CHEADERS([c_std]) GLIBCPP_ENABLE_THREADS GLIBCPP_ENABLE_CXX_FLAGS([none]) +GLIBCPP_ENABLE_SJLJ_EXCEPTIONS if test -n "$with_cross_host"; then diff --git a/libstdc++-v3/libio/Makefile.in b/libstdc++-v3/libio/Makefile.in index 2f1f8cfb736..2f203f7eb74 100644 --- a/libstdc++-v3/libio/Makefile.in +++ b/libstdc++-v3/libio/Makefile.in @@ -110,7 +110,7 @@ toplevel_srcdir = @toplevel_srcdir@ AUTOMAKE_OPTIONS = 1.3 cygnus mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs -@GLIBCPP_BUILD_LIBIO_TRUE@noinst_LTLIBRARIES = @GLIBCPP_BUILD_LIBIO_TRUE@libio.la +@GLIBCPP_BUILD_LIBIO_TRUE@noinst_LTLIBRARIES = libio.la @GLIBCPP_BUILD_LIBIO_FALSE@noinst_LTLIBRARIES = # Use common includes from acinclude.m4/GLIBCPP_EXPORT_INCLUDES @@ -122,21 +122,14 @@ LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ LIBIO_INCLUDES = @LIBIO_INCLUDES@ CSHADOW_INCLUDES = @CSHADOW_INCLUDES@ -INCLUDES = \ - -nostdinc++ \ - -I$(top_builddir)/include -I$(GLIBCPP_INCLUDE_DIR) \ - $(LIBIO_INCLUDES) $(TOPLEVEL_INCLUDES) +INCLUDES = -nostdinc++ -I$(top_builddir)/include -I$(GLIBCPP_INCLUDE_DIR) $(LIBIO_INCLUDES) $(TOPLEVEL_INCLUDES) -libio_headers = \ - libio.h libioP.h iolibio.h +libio_headers = libio.h libioP.h iolibio.h -@GLIBCPP_NEED_LIBIO_TRUE@LIBIO_SRCS = @GLIBCPP_NEED_LIBIO_TRUE@\ -@GLIBCPP_NEED_LIBIO_TRUE@ filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c \ -@GLIBCPP_NEED_LIBIO_TRUE@ iofclose.c iofopen.c +@GLIBCPP_NEED_LIBIO_TRUE@LIBIO_SRCS = filedoalloc.c genops.c fileops.c stdfiles.c c_codecvt.c iofclose.c iofopen.c @GLIBCPP_NEED_LIBIO_FALSE@LIBIO_SRCS = -@GLIBCPP_NEED_WLIBIO_TRUE@LIBIO_WSRCS = @GLIBCPP_NEED_WLIBIO_TRUE@\ -@GLIBCPP_NEED_WLIBIO_TRUE@ wfiledoalloc.c wfileops.c wgenops.c iofwide.c +@GLIBCPP_NEED_WLIBIO_TRUE@LIBIO_WSRCS = wfiledoalloc.c wfileops.c wgenops.c iofwide.c @GLIBCPP_NEED_WLIBIO_FALSE@LIBIO_WSRCS = EXTRA_DIST = iostreamP.h @@ -299,7 +292,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/libstdc++-v3/libmath/Makefile.in b/libstdc++-v3/libmath/Makefile.in index 94ba3c2286a..0ff3b818409 100644 --- a/libstdc++-v3/libmath/Makefile.in +++ b/libstdc++-v3/libmath/Makefile.in @@ -113,24 +113,18 @@ mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs noinst_LTLIBRARIES = libmath.la -EXTRA_LONG_DOUBLE_yes = \ - hypotl.c signbitl.c +EXTRA_LONG_DOUBLE_yes = hypotl.c signbitl.c -EXTRA_DIST = \ - hypot.c hypotf.c atan2f.c expf.c \ - $(EXTRA_LONG_DOUBLE_yes) +EXTRA_DIST = hypot.c hypotf.c atan2f.c expf.c $(EXTRA_LONG_DOUBLE_yes) -libmath_la_LIBADD = \ - @LIBMATHOBJS@ \ - $(EXTRA_LONG_DOUBLE_$(USE_COMPLEX_LONG_DOUBLE)) +libmath_la_LIBADD = @LIBMATHOBJS@ $(EXTRA_LONG_DOUBLE_$(USE_COMPLEX_LONG_DOUBLE)) libmath_la_DEPENDENCIES = $(libmath_la_LIBADD) -libmath_la_SOURCES = \ - signbit.c signbitf.c +libmath_la_SOURCES = signbit.c signbitf.c LINK = $(LIBTOOL) --mode=link "$(CCLD)" $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ @@ -144,9 +138,7 @@ LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ LIBIO_INCLUDES = @LIBIO_INCLUDES@ CSHADOW_INCLUDES = @CSHADOW_INCLUDES@ -INCLUDES = \ - -I$(GLIBCPP_INCLUDE_DIR) -I$(top_builddir)/include \ - $(TOPLEVEL_INCLUDES) +INCLUDES = -I$(GLIBCPP_INCLUDE_DIR) -I$(top_builddir)/include $(TOPLEVEL_INCLUDES) CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -277,7 +269,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am index 469403234f7..ad08c0e6ee6 100644 --- a/libstdc++-v3/libsupc++/Makefile.am +++ b/libstdc++-v3/libsupc++/Makefile.am @@ -75,7 +75,14 @@ sources = \ del_opnt.cc \ del_opv.cc \ del_opvnt.cc \ - exception_support.cc \ + eh_alloc.cc \ + eh_aux_runtime.cc \ + eh_catch.cc \ + eh_exception.cc \ + eh_globals.cc \ + eh_personality.cc \ + eh_terminate.cc \ + eh_throw.cc \ new_handler.cc \ new_op.cc \ new_opnt.cc \ diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index 79fe2e9f050..bdc13160450 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -127,13 +127,11 @@ OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ # These bits are all figured out from configure. Look in acinclude.m4 # or configure.in to see how they are set. See GLIBCPP_EXPORT_FLAGS # NB: DEBUGFLAGS have to be at the end so that -O2 can be overridden. -CONFIG_CXXFLAGS = \ - @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@ +CONFIG_CXXFLAGS = @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@ # Warning flags to use. -WARN_CXXFLAGS = \ - @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once +WARN_CXXFLAGS = @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once # Use common includes from acinclude.m4/GLIBCPP_EXPORT_INCLUDES @@ -145,31 +143,13 @@ LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ LIBIO_INCLUDES = @LIBIO_INCLUDES@ TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@ -INCLUDES = \ - -I$(toplevel_srcdir)/gcc -I$(toplevel_srcdir)/include \ - -I$(GLIBCPP_INCLUDE_DIR) $(CSTD_INCLUDES) -I$(top_builddir)/include \ - $(LIBSUPCXX_INCLUDES) +INCLUDES = -I$(toplevel_srcdir)/gcc -I$(toplevel_srcdir)/include -I$(GLIBCPP_INCLUDE_DIR) $(CSTD_INCLUDES) -I$(top_builddir)/include $(LIBSUPCXX_INCLUDES) -headers = \ - exception new typeinfo cxxabi.h exception_defines.h +headers = exception new typeinfo cxxabi.h exception_defines.h -sources = \ - del_op.cc \ - del_opnt.cc \ - del_opv.cc \ - del_opvnt.cc \ - exception_support.cc \ - new_handler.cc \ - new_op.cc \ - new_opnt.cc \ - new_opv.cc \ - new_opvnt.cc \ - pure.cc \ - tinfo.cc \ - tinfo2.cc \ - vec.cc +sources = del_op.cc del_opnt.cc del_opv.cc del_opvnt.cc eh_alloc.cc eh_aux_runtime.cc eh_catch.cc eh_exception.cc eh_globals.cc eh_personality.cc eh_terminate.cc eh_throw.cc new_handler.cc new_op.cc new_opnt.cc new_opv.cc new_opvnt.cc pure.cc tinfo.cc tinfo2.cc vec.cc libsupc___la_SOURCES = $(sources) @@ -187,12 +167,7 @@ LIBSUPCXX_CXXFLAGS = -prefer-pic # set this option because CONFIG_CXXFLAGS has to be after # OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden # as the occasion call for it. (ie, --enable-debug) -AM_CXXFLAGS = \ - -fno-implicit-templates \ - $(LIBSUPCXX_CXXFLAGS) \ - $(WARN_CXXFLAGS) \ - $(OPTIMIZE_CXXFLAGS) \ - $(CONFIG_CXXFLAGS) +AM_CXXFLAGS = -fno-implicit-templates $(LIBSUPCXX_CXXFLAGS) $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) # libstdc++ libtool notes @@ -216,9 +191,7 @@ AM_CXXFLAGS = \ # # We have to put --tag disable-shared after --tag CXX lest things # CXX undo the affect of disable-shared. -LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \ - --mode=compile $(CXX) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared --mode=compile $(CXX) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) # 3) We'd have a problem when building the shared libstdc++ object if @@ -227,8 +200,7 @@ LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \ # course is problematic at this point. So, we get the top-level # directory to configure libstdc++-v3 to use gcc as the C++ # compilation driver. -CXXLINK = $(LIBTOOL) --tag CXX --mode=link $(CXX) \ - @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@ +CXXLINK = $(LIBTOOL) --tag CXX --mode=link $(CXX) @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@ CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -242,13 +214,16 @@ LIBS = @LIBS@ libsupc__convenience_la_LDFLAGS = libsupc__convenience_la_LIBADD = libsupc__convenience_la_OBJECTS = del_op.lo del_opnt.lo del_opv.lo \ -del_opvnt.lo exception_support.lo new_handler.lo new_op.lo new_opnt.lo \ -new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo +del_opvnt.lo eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo \ +eh_globals.lo eh_personality.lo eh_terminate.lo eh_throw.lo \ +new_handler.lo new_op.lo new_opnt.lo new_opv.lo new_opvnt.lo pure.lo \ +tinfo.lo tinfo2.lo vec.lo libsupc___la_LDFLAGS = libsupc___la_LIBADD = libsupc___la_OBJECTS = del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo \ -exception_support.lo new_handler.lo new_op.lo new_opnt.lo new_opv.lo \ -new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo +eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo eh_globals.lo \ +eh_personality.lo eh_terminate.lo eh_throw.lo new_handler.lo new_op.lo \ +new_opnt.lo new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo CXXFLAGS = @CXXFLAGS@ CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) @@ -417,7 +392,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc new file mode 100644 index 00000000000..61dc75d159b --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -0,0 +1,157 @@ +// -*- C++ -*- Allocate exception objects. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This is derived from the C++ ABI for IA-64. Where we diverge +// for cross-architecture compatibility are noted with "@@@". + +#include +#include +#include +#include +#include "unwind-cxx.h" +#include "gthr.h" + +using namespace __cxxabiv1; + + +// ??? How to control these parameters. + +// Guess from the size of basic types how large a buffer is reasonable. +// Note that the basic c++ exception header has 13 pointers and 2 ints, +// so on a system with PSImode pointers we're talking about 56 bytes +// just for overhead. + +#if INT_MAX == 32767 +# define EMERGENCY_OBJ_SIZE 128 +# define EMERGENCY_OBJ_COUNT 16 +#elif LONG_MAX == 2147483647 +# define EMERGENCY_OBJ_SIZE 512 +# define EMERGENCY_OBJ_COUNT 32 +#else +# define EMERGENCY_OBJ_SIZE 1024 +# define EMERGENCY_OBJ_COUNT 64 +#endif + +#ifndef __GTHREADS +# undef EMERGENCY_OBJ_COUNT +# define EMERGENCY_OBJ_COUNT 4 +#endif + +#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32 +typedef unsigned int bitmask_type; +#else +typedef unsigned long bitmask_type; +#endif + + +typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned)); +static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT]; +static bitmask_type emergency_used; + + +#ifdef __GTHREADS +#ifdef __GTHREAD_MUTEX_INIT +static __gthread_mutex_t emergency_mutex =__GTHREAD_MUTEX_INIT; +#else +static __gthread_mutex_t emergency_mutex; +#endif + +#ifdef __GTHREAD_MUTEX_INIT_FUNCTION +static void +emergency_mutex_init () +{ + __GTHREAD_MUTEX_INIT_FUNCTION (&emergency_mutex); +} +#endif +#endif + + +extern "C" void * +__cxa_allocate_exception(std::size_t thrown_size) +{ + void *ret; + + thrown_size += sizeof (__cxa_exception); + ret = malloc (thrown_size); + + if (! ret) + { +#ifdef __GTHREADS +#ifdef __GTHREAD_MUTEX_INIT_FUNCTION + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + __gthread_once (&once, emergency_mutex_init); +#endif + __gthread_mutex_lock (&emergency_mutex); +#endif + + bitmask_type used = emergency_used; + unsigned int which = 0; + + while (used & 1) + { + used >>= 1; + if (++which >= EMERGENCY_OBJ_COUNT) + std::terminate (); + } + + emergency_used |= (bitmask_type)1 << which; + ret = &emergency_buffer[which][0]; + +#ifdef __GTHREADS + __gthread_mutex_unlock (&emergency_mutex); +#endif + } + + memset (ret, 0, sizeof (__cxa_exception)); + + return (void *)((char *)ret + sizeof (__cxa_exception)); +} + + +extern "C" void +__cxa_free_exception(void *vptr) +{ + char *ptr = (char *) vptr; + if (ptr >= &emergency_buffer[0][0] + && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer)) + { + unsigned int which + = (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE; + +#ifdef __GTHREADS + __gthread_mutex_lock (&emergency_mutex); + emergency_used &= ~((bitmask_type)1 << which); + __gthread_mutex_unlock (&emergency_mutex); +#else + emergency_used &= ~((bitmask_type)1 << which); +#endif + } + else + free (ptr - sizeof (__cxa_exception)); +} diff --git a/libstdc++-v3/libsupc++/eh_aux_runtime.cc b/libstdc++-v3/libsupc++/eh_aux_runtime.cc new file mode 100644 index 00000000000..b10a21986e6 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_aux_runtime.cc @@ -0,0 +1,56 @@ +// -*- C++ -*- Common throw conditions. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +// Free Software Foundation +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include "typeinfo" +#include "exception" +#include +#include "unwind-cxx.h" +#include "exception_defines.h" + + +extern "C" void +__cxa_bad_cast () +{ +#ifdef __EXCEPTIONS + throw std::bad_cast(); +#else + std::abort(); +#endif +} + +extern "C" void +__cxa_bad_typeid () +{ +#ifdef __EXCEPTIONS + throw std::bad_typeid(); +#else + std::abort(); +#endif +} diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc new file mode 100644 index 00000000000..4f55d68e477 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_catch.cc @@ -0,0 +1,103 @@ +// -*- C++ -*- Exception handling routines for catching. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#include +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + + +extern "C" void * +__cxa_begin_catch (_Unwind_Exception *exceptionObject) +{ + // ??? Foreign exceptions can't be stacked here, and there doesn't + // appear to be any place to store for __cxa_end_catch to destroy. + + __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *prev = globals->caughtExceptions; + int count = header->handlerCount; + + if (count < 0) + // This exception was rethrown from an immediately enclosing region. + count = -count + 1; + else + count += 1; + header->handlerCount = count; + + globals->uncaughtExceptions -= 1; + if (header != prev) + { + header->nextException = prev; + globals->caughtExceptions = header; + } + + return header->adjustedPtr; +} + + +extern "C" void +__cxa_end_catch () +{ + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + __cxa_exception *header = globals->caughtExceptions; + int count = header->handlerCount; + + if (count < 0) + { + // This exception was rethrown. Decrement the (inverted) catch + // count and remove it from the chain when it reaches zero. + if (++count == 0) + { + globals->uncaughtExceptions += 1; + globals->caughtExceptions = header->nextException; + } + } + else if (--count == 0) + { + // Handling for this exception is complete. Destroy the object. + globals->caughtExceptions = header->nextException; + _Unwind_DeleteException (&header->unwindHeader); + return; + } + else if (count < 0) + // A bug in the exception handling library or compiler. + abort (); + + header->handlerCount = count; +} + + +bool +std::uncaught_exception() throw() +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + return globals->uncaughtExceptions != 0; +} diff --git a/libstdc++-v3/libsupc++/eh_exception.cc b/libstdc++-v3/libsupc++/eh_exception.cc new file mode 100644 index 00000000000..3c1a7a44ccb --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_exception.cc @@ -0,0 +1,44 @@ +// -*- C++ -*- std::exception implementation. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +// Free Software Foundation +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#include "typeinfo" +#include "exception" +#include "unwind-cxx.h" + +std::exception::~exception() throw() { } + +std::bad_exception::~bad_exception() throw() { } + +const char* +std::exception::what() const throw() +{ + return typeid (*this).name (); +} diff --git a/libstdc++-v3/libsupc++/eh_globals.cc b/libstdc++-v3/libsupc++/eh_globals.cc new file mode 100644 index 00000000000..a247b842f59 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_globals.cc @@ -0,0 +1,120 @@ +// -*- C++ -*- Manage the thread-local exception globals. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#include +#include "unwind-cxx.h" +#include "gthr.h" + +using namespace __cxxabiv1; + + +// Single-threaded fallback buffer. +static __cxa_eh_globals globals_static; + +#if __GTHREADS +static __gthread_key_t globals_key; +static int use_thread_key = -1; + +static void +get_globals_dtor (void *ptr) +{ + __gthread_key_dtor (globals_key, ptr); + if (ptr) + free (ptr); +} + +static void +get_globals_init () +{ + use_thread_key = + (__gthread_key_create (&globals_key, get_globals_dtor) == 0); +} + +static void +get_globals_init_once () +{ + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + if (__gthread_once (&once, get_globals_init) != 0 + || use_thread_key < 0) + use_thread_key = 0; +} +#endif + +extern "C" __cxa_eh_globals * +__cxa_get_globals_fast () +{ +#if __GTHREADS + if (use_thread_key) + return (__cxa_eh_globals *) __gthread_getspecific (globals_key); + else + return &globals_static; +#else + return &globals_static; +#endif +} + +extern "C" __cxa_eh_globals * +__cxa_get_globals () +{ +#if __GTHREADS + __cxa_eh_globals *g; + + if (use_thread_key == 0) + return &globals_static; + + if (use_thread_key < 0) + get_globals_init_once (); + + g = (__cxa_eh_globals *) __gthread_getspecific (globals_key); + if (! g) + { + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + + // Make sure use_thread_key got initialized. Some systems have + // dummy thread routines in their libc that return a success. + if (__gthread_once (&once, eh_threads_initialize) != 0 + || use_thread_key < 0) + { + use_thread_key = 0; + return &globals_static; + } + + if ((g = malloc (sizeof (__cxa_eh_globals))) == 0 + || __gthread_setspecific (eh_context_key, (void *) g) != 0) + std::terminate (); + g->caughtExceptions = 0; + g->uncaughtExceptions = 0; + } + + return g; +#else + return &globals_static; +#endif +} diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc new file mode 100644 index 00000000000..5dfadc94438 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -0,0 +1,599 @@ +// -*- C++ -*- The GNU C++ exception personality routine. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#include +#include +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + + + +// ??? These ought to go somewhere else dwarf2 or dwarf2eh related. + +// Pointer encodings. +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_omit 0xff + +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_signed 0x08 + +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 + +static unsigned int +size_of_encoded_value (unsigned char encoding) +{ + switch (encoding & 0x07) + { + case DW_EH_PE_absptr: + return sizeof (void *); + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + } + abort (); +} + +static const unsigned char * +read_encoded_value (_Unwind_Context *context, unsigned char encoding, + const unsigned char *p, _Unwind_Ptr *val) +{ + union unaligned + { + void *ptr; + unsigned u2 __attribute__ ((mode (HI))); + unsigned u4 __attribute__ ((mode (SI))); + unsigned u8 __attribute__ ((mode (DI))); + signed s2 __attribute__ ((mode (HI))); + signed s4 __attribute__ ((mode (SI))); + signed s8 __attribute__ ((mode (DI))); + } __attribute__((__packed__)); + + union unaligned *u = (union unaligned *) p; + _Unwind_Ptr result; + + switch (encoding & 0x0f) + { + case DW_EH_PE_absptr: + result = (_Unwind_Ptr) u->ptr; + p += sizeof (void *); + break; + + case DW_EH_PE_uleb128: + { + unsigned int shift = 0; + unsigned char byte; + + result = 0; + do + { + byte = *p++; + result |= (_Unwind_Ptr)(byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + } + break; + + case DW_EH_PE_sleb128: + { + unsigned int shift = 0; + unsigned char byte; + + result = 0; + do + { + byte = *p++; + result |= (_Unwind_Ptr)(byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) + result |= -(1L << shift); + } + break; + + case DW_EH_PE_udata2: + result = u->u2; + p += 2; + break; + case DW_EH_PE_udata4: + result = u->u4; + p += 4; + break; + case DW_EH_PE_udata8: + result = u->u8; + p += 8; + break; + + case DW_EH_PE_sdata2: + result = u->s2; + p += 2; + break; + case DW_EH_PE_sdata4: + result = u->s4; + p += 4; + break; + case DW_EH_PE_sdata8: + result = u->s8; + p += 8; + break; + + default: + abort (); + } + + if (result != 0) + switch (encoding & 0xf0) + { + case DW_EH_PE_absptr: + break; + + case DW_EH_PE_pcrel: + // Define as relative to the beginning of the pointer. + result += (_Unwind_Ptr) u; + break; + + case DW_EH_PE_textrel: + case DW_EH_PE_datarel: + // FIXME. + abort (); + + case DW_EH_PE_funcrel: + result += _Unwind_GetRegionStart (context); + break; + + default: + abort (); + } + + *val = result; + return p; +} + +static inline const unsigned char * +read_uleb128 (const unsigned char *p, _Unwind_Ptr *val) +{ + return read_encoded_value (0, DW_EH_PE_uleb128, p, val); +} + +static inline const unsigned char * +read_sleb128 (const unsigned char *p, _Unwind_Ptr *val) +{ + return read_encoded_value (0, DW_EH_PE_sleb128, p, val); +} + + +struct lsda_header_info +{ + _Unwind_Ptr Start; + _Unwind_Ptr LPStart; + const unsigned char *TType; + const unsigned char *action_table; + unsigned char ttype_encoding; + unsigned char call_site_encoding; +}; + +static const unsigned char * +parse_lsda_header (_Unwind_Context *context, const unsigned char *p, + lsda_header_info *info) +{ + _Unwind_Ptr tmp; + unsigned char lpstart_encoding; + + info->Start = (context ? _Unwind_GetRegionStart (context) : 0); + + // Find @LPStart, the base to which landing pad offsets are relative. + lpstart_encoding = *p++; + if (lpstart_encoding != DW_EH_PE_omit) + p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart); + else + info->LPStart = info->Start; + + // Find @TType, the base of the handler and exception spec type data. + info->ttype_encoding = *p++; + if (info->ttype_encoding != DW_EH_PE_omit) + { + p = read_uleb128 (p, &tmp); + info->TType = p + tmp; + } + else + info->TType = 0; + + // The encoding and length of the call-site table; the action table + // immediately follows. + info->call_site_encoding = *p++; + p = read_uleb128 (p, &tmp); + info->action_table = p + tmp; + + return p; +} + +static const std::type_info * +get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i) +{ + _Unwind_Ptr ptr; + + i *= size_of_encoded_value (info->ttype_encoding); + read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr); + + return reinterpret_cast(ptr); +} + +static bool +check_exception_spec (_Unwind_Context *context, lsda_header_info *info, + const std::type_info *throw_type, long filter_value) +{ + const unsigned char *e = info->TType - filter_value - 1; + + while (1) + { + const std::type_info *catch_type; + _Unwind_Ptr tmp; + void *dummy; + + e = read_uleb128 (e, &tmp); + + // Zero signals the end of the list. If we've not found + // a match by now, then we've failed the specification. + if (tmp == 0) + return false; + + // Match a ttype entry. + catch_type = get_ttype_entry (context, info, tmp); + if (catch_type->__do_catch (throw_type, &dummy, 1)) + return true; + } +} + +// Using a different personality function name causes link failures +// when trying to mix code using different exception handling models. +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS +#define PERSONALITY_FUNCTION __gxx_personality_sj0 +#define __builtin_eh_return_data_regno(x) x +#else +#define PERSONALITY_FUNCTION __gxx_personality_v0 +#endif + +extern "C" _Unwind_Reason_Code +PERSONALITY_FUNCTION (int version, + _Unwind_Action actions, + _Unwind_Exception_Class exception_class, + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) +{ + __cxa_exception *xh = __get_exception_header_from_ue (ue_header); + + enum found_handler_type + { + found_nothing, + found_terminate, + found_cleanup, + found_handler + } found_type; + + lsda_header_info info; + const unsigned char *language_specific_data; + const unsigned char *action_record; + const unsigned char *p; + _Unwind_Ptr landing_pad, ip; + int handler_switch_value; + void *adjusted_ptr = xh + 1; + + // Interface version check. + if (version != 1) + return _URC_FATAL_PHASE1_ERROR; + + // Shortcut for phase 2 found handler for domestic exception. + if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) + && exception_class == __gxx_exception_class) + { + handler_switch_value = xh->handlerSwitchValue; + landing_pad = (_Unwind_Ptr) xh->catchTemp; + found_type = (landing_pad == 0 ? found_terminate : found_handler); + goto install_context; + } + + language_specific_data = (const unsigned char *) + _Unwind_GetLanguageSpecificData (context); + + // If no LSDA, then there are no handlers or cleanups. + if (! language_specific_data) + return _URC_CONTINUE_UNWIND; + + // Parse the LSDA header. + p = parse_lsda_header (context, language_specific_data, &info); + ip = _Unwind_GetIP (context) - 1; + landing_pad = 0; + action_record = 0; + handler_switch_value = 0; + +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS + // The given "IP" is an index into the call-site table, with two + // exceptions -- -1 means no-action, and 0 means terminate. But + // since we're using uleb128 values, we've not got random access + // to the array. + if ((int) ip < 0) + return _URC_CONTINUE_UNWIND; + else if (ip == 0) + { + // Fall through to set found_terminate. + } + else + { + _Unwind_Ptr cs_lp, cs_action; + do + { + p = read_uleb128 (p, &cs_lp); + p = read_uleb128 (p, &cs_action); + } + while (--ip); + + // Can never have null landing pad for sjlj -- that would have + // been indicated by a -1 call site index. + landing_pad = cs_lp + 1; + if (cs_action) + action_record = info.action_table + cs_action - 1; + goto found_something; + } +#else + // Search the call-site table for the action associated with this IP. + while (p < info.action_table) + { + _Unwind_Ptr cs_start, cs_len, cs_lp, cs_action; + + // Note that all call-site encodings are "absolute" displacements. + p = read_encoded_value (0, info.call_site_encoding, p, &cs_start); + p = read_encoded_value (0, info.call_site_encoding, p, &cs_len); + p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp); + p = read_uleb128 (p, &cs_action); + + // The table is sorted, so if we've passed the ip, stop. + if (ip < info.Start + cs_start) + p = info.action_table; + else if (ip < info.Start + cs_start + cs_len) + { + if (cs_lp) + landing_pad = info.LPStart + cs_lp; + if (cs_action) + action_record = info.action_table + cs_action - 1; + goto found_something; + } + } +#endif // _GLIBCPP_SJLJ_EXCEPTIONS + + // If ip is not present in the table, call terminate. This is for + // a destructor inside a cleanup, or a library routine the compiler + // was not expecting to throw. + found_type = (actions & _UA_FORCE_UNWIND ? found_nothing : found_terminate); + goto do_something; + + found_something: + if (landing_pad == 0) + { + // If ip is present, and has a null landing pad, there are + // no cleanups or handlers to be run. + found_type = found_nothing; + } + else if (action_record == 0) + { + // If ip is present, has a non-null landing pad, and a null + // action table offset, then there are only cleanups present. + // Cleanups use a zero switch value, as set above. + found_type = found_cleanup; + } + else + { + // Otherwise we have a catch handler or exception specification. + + signed long ar_filter, ar_disp; + const std::type_info *throw_type, *catch_type; + bool saw_cleanup = false; + bool saw_handler = false; + + // During forced unwinding, we only run cleanups. With a foreign + // exception class, there's no exception type. + // ??? What to do about GNU Java and GNU Ada exceptions. + + if ((actions & _UA_FORCE_UNWIND) + || exception_class != __gxx_exception_class) + throw_type = 0; + else + throw_type = xh->exceptionType; + + while (1) + { + _Unwind_Ptr tmp; + + p = action_record; + p = read_sleb128 (p, &tmp); ar_filter = tmp; + read_sleb128 (p, &tmp); ar_disp = tmp; + + if (ar_filter == 0) + { + // Zero filter values are cleanups. + saw_cleanup = true; + } + else if (ar_filter > 0) + { + // Positive filter values are handlers. + catch_type = get_ttype_entry (context, &info, ar_filter); + adjusted_ptr = xh + 1; + + // Null catch type is a catch-all handler. We can catch + // foreign exceptions with this. + if (! catch_type) + { + if (!(actions & _UA_FORCE_UNWIND)) + { + saw_handler = true; + break; + } + } + else if (throw_type) + { + // Pointer types need to adjust the actual pointer, not + // the pointer to pointer that is the exception object. + // This also has the effect of passing pointer types + // "by value" through the __cxa_begin_catch return value. + if (throw_type->__is_pointer_p ()) + adjusted_ptr = *(void **) adjusted_ptr; + + if (catch_type->__do_catch (throw_type, &adjusted_ptr, 1)) + { + saw_handler = true; + break; + } + } + } + else + { + // Negative filter values are exception specifications. + // ??? How do foreign exceptions fit in? As far as I can + // see we can't match because there's no __cxa_exception + // object to stuff bits in for __cxa_call_unexpected to use. + if (throw_type + && ! check_exception_spec (context, &info, throw_type, + ar_filter)) + { + saw_handler = true; + break; + } + } + + if (ar_disp == 0) + break; + action_record = p + ar_disp; + } + + if (saw_handler) + { + handler_switch_value = ar_filter; + found_type = found_handler; + } + else + found_type = (saw_cleanup ? found_cleanup : found_nothing); + } + + do_something: + if (found_type == found_nothing) + return _URC_CONTINUE_UNWIND; + + if (actions & _UA_SEARCH_PHASE) + { + if (found_type == found_cleanup) + return _URC_CONTINUE_UNWIND; + + // For domestic exceptions, we cache data from phase 1 for phase 2. + if (exception_class == __gxx_exception_class) + { + xh->handlerSwitchValue = handler_switch_value; + xh->actionRecord = action_record; + xh->languageSpecificData = language_specific_data; + xh->adjustedPtr = adjusted_ptr; + + // ??? Completely unknown what this field is supposed to be for. + // ??? Need to cache TType encoding base for call_unexpected. + xh->catchTemp = (void *) (_Unwind_Ptr) landing_pad; + } + return _URC_HANDLER_FOUND; + } + + install_context: + if (found_type == found_terminate) + { + __cxa_begin_catch (&xh->unwindHeader); + __terminate (xh->terminateHandler); + } + + _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), + (_Unwind_Ptr) &xh->unwindHeader); + _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), + handler_switch_value); + _Unwind_SetIP (context, landing_pad); + return _URC_INSTALL_CONTEXT; +} + +extern "C" void +__cxa_call_unexpected (_Unwind_Exception *exc_obj) +{ + __cxa_begin_catch (exc_obj); + + // This function is a handler for our exception argument. If we exit + // by throwing a different exception, we'll need the original cleaned up. + struct end_catch_protect + { + end_catch_protect() { } + ~end_catch_protect() { __cxa_end_catch(); } + } end_catch_protect_obj; + + __cxa_exception *xh = __get_exception_header_from_ue (exc_obj); + + try { + __unexpected (xh->unexpectedHandler); + } catch (...) { + // Get the exception thrown from unexpected. + // ??? Foreign exceptions can't be stacked this way. + + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + __cxa_exception *new_xh = globals->caughtExceptions; + + // We don't quite have enough stuff cached; re-parse the LSDA. + lsda_header_info info; + parse_lsda_header (0, xh->languageSpecificData, &info); + + // If this new exception meets the exception spec, allow it. + if (check_exception_spec (0, &info, new_xh->exceptionType, + xh->handlerSwitchValue)) + throw; + + // If the exception spec allows std::bad_exception, throw that. + const std::type_info &bad_exc = typeid (std::bad_exception); + if (check_exception_spec (0, &info, &bad_exc, xh->handlerSwitchValue)) + throw std::bad_exception (); + + // Otherwise, die. + __terminate(xh->terminateHandler); + } +} diff --git a/libstdc++-v3/libsupc++/eh_terminate.cc b/libstdc++-v3/libsupc++/eh_terminate.cc new file mode 100644 index 00000000000..11d5829f5de --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_terminate.cc @@ -0,0 +1,87 @@ +// -*- C++ -*- std::terminate, std::unexpected and friends. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +// Free Software Foundation +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include "typeinfo" +#include "exception" +#include +#include "unwind-cxx.h" +#include "exception_defines.h" + +using namespace __cxxabiv1; + +/* The current installed user handlers. */ +std::terminate_handler __cxxabiv1::__terminate_handler = abort; +std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate; + +void +__cxxabiv1::__terminate (std::terminate_handler handler) +{ + try { + handler (); + abort (); + } catch (...) { + abort (); + } +} + +void +std::terminate () +{ + __terminate (__terminate_handler); +} + +void +__cxxabiv1::__unexpected (std::unexpected_handler handler) +{ + handler(); + std::terminate (); +} + +void +std::unexpected () +{ + __unexpected (__unexpected_handler); +} + +std::terminate_handler +std::set_terminate (std::terminate_handler func) throw() +{ + std::terminate_handler old = __terminate_handler; + __terminate_handler = func; + return old; +} + +std::unexpected_handler +std::set_unexpected (std::unexpected_handler func) throw() +{ + std::unexpected_handler old = __unexpected_handler; + __unexpected_handler = func; + return old; +} diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc new file mode 100644 index 00000000000..a8e9ba34557 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -0,0 +1,102 @@ +// -*- C++ -*- Exception handling routines for throwing. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#include +#include "unwind-cxx.h" + + +using namespace __cxxabiv1; + + +static void +__gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) +{ + __cxa_exception *header = __get_exception_header_from_ue (exc); + + // If we havn't been caught by a foreign handler, then this is + // some sort of unwind error. In that case just die immediately. + if (code != _URC_FOREIGN_EXCEPTION_CAUGHT) + __terminate (header->terminateHandler); + + if (header->exceptionDestructor) + header->exceptionDestructor (header + 1); + + __cxa_free_exception (header + 1); +} + + +extern "C" void +__cxa_throw (void *obj, std::type_info *tinfo, void (*dest) (void *)) +{ + __cxa_exception *header = __get_exception_header_from_obj (obj); + header->exceptionType = tinfo; + header->exceptionDestructor = dest; + header->unexpectedHandler = __unexpected_handler; + header->terminateHandler = __terminate_handler; + header->unwindHeader.exception_class = __gxx_exception_class; + header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; + + __cxa_eh_globals *globals = __cxa_get_globals (); + globals->uncaughtExceptions += 1; + +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS + _Unwind_SjLj_RaiseException (&header->unwindHeader); +#else + _Unwind_RaiseException (&header->unwindHeader); +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&header->unwindHeader); + std::terminate (); +} + +extern "C" void +__cxa_rethrow () +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *header = globals->caughtExceptions; + + // Watch for luser rethrowing with no active exception. + if (header) + { + // Tell __cxa_end_catch this is a rethrow. + header->handlerCount = -header->handlerCount; + +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS + _Unwind_SjLj_RaiseException (&header->unwindHeader); +#else + _Unwind_RaiseException (&header->unwindHeader); +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&header->unwindHeader); + } + std::terminate (); +} diff --git a/libstdc++-v3/libsupc++/exception_support.cc b/libstdc++-v3/libsupc++/exception_support.cc deleted file mode 100644 index 48adafa4ab9..00000000000 --- a/libstdc++-v3/libsupc++/exception_support.cc +++ /dev/null @@ -1,388 +0,0 @@ -// Functions for Exception Support for -*- C++ -*- - -// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -// Free Software Foundation -// -// This file is part of GNU CC. -// -// GNU CC is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2, or (at your option) -// any later version. - -// GNU CC is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with GNU CC; see the file COPYING. If not, write to -// the Free Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include "typeinfo" -#include "exception" -#include -#include "exception_support.h" -#include "exception_defines.h" - -/* Define terminate, unexpected, set_terminate, set_unexpected as - well as the default terminate func and default unexpected func. */ - -/* __terminate and __terminate_set_func, defined in libgcc2. */ -typedef void (*__terminate_func_ptr)(void) __attribute__ ((__noreturn__)); -extern "C" void __terminate (void) __attribute__ ((__noreturn__)); -extern "C" __terminate_func_ptr __terminate_set_func (__terminate_func_ptr); - -using std::terminate; - -void -std::terminate () -{ - __terminate (); -} - -void -__default_unexpected () -{ - terminate (); -} - -static std::unexpected_handler __unexpected_func __attribute__((__noreturn__)) - = __default_unexpected; - -std::terminate_handler -std::set_terminate (std::terminate_handler func) throw() -{ - return __terminate_set_func (func); -} - -std::unexpected_handler -std::set_unexpected (std::unexpected_handler func) throw() -{ - std::unexpected_handler old = __unexpected_func; - - __unexpected_func = func; - return old; -} - -void -std::unexpected () -{ - __unexpected_func (); -} - -/* Language-specific EH info pointer, defined in libgcc2. */ -extern "C" cp_eh_info **__get_eh_info (); // actually void ** -#define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ()) - -/* Exception allocate and free, defined in libgcc2. */ -extern "C" void *__eh_alloc(std::size_t); -extern "C" void __eh_free(void *); - -/* Is P the type_info node for a pointer of some kind? */ -extern bool __is_pointer (void *); - - -#ifdef __EXCEPTIONS -/* OLD Compiler hook to return a pointer to the info for the current exception. - Used by get_eh_info (). This fudges the actualy returned value to - point to the beginning of what USE to be the cp_eh_info structure. - THis is so that old code that dereferences this pointer will find - things where it expects it to be.*/ -extern "C" void * -__cp_exception_info (void) -{ - return &((*__get_eh_info ())->value); -} - -/* Old Compiler hook to return a pointer to the info for the current exception. - Used by get_eh_info (). */ - -extern "C" cp_eh_info * -__cp_eh_info (void) -{ - cp_eh_info *p = CP_EH_INFO; - return p; -} - -/* Compiler hook to return a pointer to the info for the current exception, - Set the caught bit, and increment the number of handlers that are - looking at this exception. This makes handlers smaller. */ - -extern "C" cp_eh_info * -__start_cp_handler (void) -{ - cp_eh_info *p = CP_EH_INFO; - p->caught = 1; - p->handlers++; - return p; -} - -extern "C" int __throw_type_match_rtti_2 (const void *, const void *, - void *, void **); - -extern "C" void * -__cplus_type_matcher (__eh_info *info_, void *match_info, - exception_descriptor *exception_table) -{ - cp_eh_info *info = (cp_eh_info *)info_; - - /* No exception table implies the old style mechanism, so don't check. */ - if (exception_table != NULL - && exception_table->lang.language != EH_LANG_C_plus_plus) - return NULL; - - if (match_info == CATCH_ALL_TYPE) - return (void *)1; - - /* we don't worry about version info yet, there is only one version! */ - - void *match_type = match_info; - - if (__throw_type_match_rtti_2 (match_type, info->type, - info->original_value, &info->value)) - // Arbitrary non-null pointer. - return (void *)1; - else - return NULL; -} - -/* Compiler hook to push a new exception onto the stack. - Used by expand_throw(). */ - -extern "C" void -__cp_push_exception (void *value, void *type, cleanup_fn cleanup) -{ - cp_eh_info *p = (cp_eh_info *) __eh_alloc (sizeof (cp_eh_info)); - - p->value = value; - p->type = type; - p->cleanup = cleanup; - p->handlers = 0; - p->caught = false; - p->original_value = value; - - p->eh_info.match_function = __cplus_type_matcher; - p->eh_info.language = EH_LANG_C_plus_plus; - p->eh_info.version = 1; - - cp_eh_info **q = __get_eh_info (); - - p->next = *q; - *q = p; -} - -/* Compiler hook to pop an exception that has been finalized. Used by - push_eh_cleanup(). P is the info for the exception caught by the - current catch block. */ - -extern "C" void -__cp_pop_exception (void* p_) -{ - cp_eh_info *p = static_cast (p_); - cp_eh_info **stack = __get_eh_info (); - cp_eh_info **q = stack; - - --p->handlers; - - /* Do nothing if our exception is being rethrown (i.e. if the active - exception is our exception and it is uncaught). */ - if (p == *q && !p->caught) - return; - - /* Don't really pop if there are still active handlers for our exception; - rather, push it down past any uncaught exceptions. */ - if (p->handlers != 0) - { - if (p == *q && p->next && !p->next->caught) - { - q = &(p->next); - while (1) - { - if (*q == 0 || (*q)->caught) - break; - - q = &((*q)->next); - } - *stack = p->next; - p->next = *q; - *q = p; - } - return; - } - - for (; *q; q = &((*q)->next)) - if (*q == p) - break; - - if (! *q) - terminate (); - - *q = p->next; - - if (p->cleanup) - // value may have been adjusted. - CALL_CLEANUP (p->cleanup, p->original_value); - - if (! __is_pointer (p->type)) - __eh_free (p->original_value); // value may have been adjusted. - - __eh_free (p); -} - -/* We're doing a rethrow. Find the currently handled exception, mark it - uncaught, and move it to the top of the EH stack. */ - -extern "C" cp_eh_info * -__uncatch_exception (void) -{ - cp_eh_info **stack = __get_eh_info (); - cp_eh_info **q = stack; - cp_eh_info *p; - - while (1) - { - p = *q; - - if (p == 0) - terminate (); - if (p->caught) - break; - - q = &(p->next); - } - - if (q != stack) - { - *q = p->next; - p->next = *stack; - *stack = p; - } - - p->caught = false; - - return p; -} - -/* Mark P as caught after we previously marked it as uncaught. */ - -extern "C" void -__recatch_exception (cp_eh_info *p) -{ - p->caught = true; -} - -/* As per [except.unexpected]: - If an exception is thrown, we check it against the spec. If it doesn't - match, we call unexpected (). If unexpected () throws, we check that - exception against the spec. If it doesn't match, if the spec allows - bad_exception we throw that; otherwise we call terminate (). - - The compiler treats an exception spec as a try block with a generic - handler that just calls this function with a list of the allowed - exception types, so we have an active exception that can be rethrown. - - This function does not return. */ - -extern "C" void -__check_eh_spec (int n, const void **spec) -{ - cp_eh_info *p = CP_EH_INFO; - void *d; - - for (int i = 0; i < n; ++i) - { - if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d)) - throw; - } - - try - { - std::unexpected (); - } - catch (...) - { - // __exception_info is an artificial var pushed into each catch block. - if (p != __exception_info) - { - p = __exception_info; - for (int i = 0; i < n; ++i) - { - if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d)) - throw; - } - } - - const std::type_info &bad_exc = typeid (std::bad_exception); - for (int i = 0; i < n; ++i) - { - if (__throw_type_match_rtti_2 (spec[i], &bad_exc, p->value, &d)) - throw std::bad_exception (); - } - - terminate (); - } -} - -/* Special case of the above for throw() specs. */ - -extern "C" void -__check_null_eh_spec (void) -{ - __check_eh_spec (0, 0); -} -#endif //__EXCEPTIONS - -// Helpers for rtti. Although these don't return, we give them return types so -// that the type system is not broken. -extern "C" void * -__cxa_bad_cast () -{ -#ifdef __EXCEPTIONS - throw std::bad_cast(); -#else - std::abort(); -#endif - return 0; -} - -extern "C" std::type_info const & -__cxa_bad_typeid () -{ -#ifdef __EXCEPTIONS - throw std::bad_typeid(); -#else - std::abort(); -#endif - return typeid (void); -} - -/* Has the current exception been caught? */ -bool -std::uncaught_exception() throw() -{ - cp_eh_info *p = CP_EH_INFO; - return p && ! p->caught; -} - -std::exception::~exception() throw() { } - -std::bad_exception::~bad_exception() throw() { } - -const char* -std::exception::what() const throw() -{ return typeid (*this).name (); } - - - - diff --git a/libstdc++-v3/libsupc++/exception_support.h b/libstdc++-v3/libsupc++/exception_support.h deleted file mode 100644 index cc781192ddb..00000000000 --- a/libstdc++-v3/libsupc++/exception_support.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2000 Free Software Foundation, Inc. -// -// GNU CC is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2, or (at your option) -// any later version. - -// GNU CC is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with GNU CC; see the file COPYING. If not, write to -// the Free Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include "gansidecl.h" /* Needed to support macros used in eh-common.h. */ -#include "eh-common.h" - -/* The type of a function called to clean up an exception object. - (These will be destructors.) Under the old ABI, these take a - second argument (the `in-charge' argument), that indicates whether - or not do delete the object, and whether or not to destroy virtual - bases. Under the new ABI, there is no second argument. */ -#if !defined (__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100 -typedef void (*cleanup_fn)(void *, int); -/* The `2' is the value for the in-charge parameter that indicates - that virtual bases should be destroyed. */ -#define CALL_CLEANUP(FN, THIS) FN (THIS, 2) -#else -typedef void (*cleanup_fn)(void *); -#define CALL_CLEANUP(FN, THIS) FN (THIS) -#endif - -/* C++-specific state about the current exception. This must match - init_exception_processing(). - - Note that handlers and caught are not redundant; when rethrown, an - exception can have multiple active handlers and still be considered - uncaught. */ - -struct cp_eh_info -{ - __eh_info eh_info; - void *value; - void *type; - cleanup_fn cleanup; - bool caught; - cp_eh_info *next; - long handlers; - void *original_value; -}; - -extern "C" cp_eh_info *__uncatch_exception (void); -extern "C" void __recatch_exception (cp_eh_info *); diff --git a/libstdc++-v3/libsupc++/pure.cc b/libstdc++-v3/libsupc++/pure.cc index 7373cd1739f..5f9b3c868cc 100644 --- a/libstdc++-v3/libsupc++/pure.cc +++ b/libstdc++-v3/libsupc++/pure.cc @@ -28,6 +28,7 @@ // the GNU General Public License. #include +#include "unwind-cxx.h" #ifdef _GLIBCPP_HAVE_UNISTD_H # include @@ -42,15 +43,9 @@ # define writestr(str) fputs(str, stderr) #endif -extern "C" { - -extern void __terminate(void) __attribute__ ((__noreturn__)); - -void +extern "C" void __cxa_pure_virtual (void) { writestr ("pure virtual method called\n"); - __terminate (); -} - + std::terminate (); } diff --git a/libstdc++-v3/libsupc++/tinfo2.cc b/libstdc++-v3/libsupc++/tinfo2.cc index a29d1d30f02..8f3d6319c38 100644 --- a/libstdc++-v3/libsupc++/tinfo2.cc +++ b/libstdc++-v3/libsupc++/tinfo2.cc @@ -165,31 +165,3 @@ __pointer_catch (const __pbase_type_info *thr_type, } } // namespace std - -// Entry points for the compiler. - -/* Low level match routine used by compiler to match types of catch - variables and thrown objects. */ - -extern "C" int -__throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r, - void *objptr, void **valp) -{ - const type_info &catch_type = *(const type_info *)catch_type_r; - const type_info &throw_type = *(const type_info *)throw_type_r; - - *valp = objptr; - - return catch_type.__do_catch (&throw_type, valp, 1); -} - -/* Called from __cp_pop_exception. Is P the type_info node for a pointer - of some kind? */ - -bool -__is_pointer (void *p) -{ - const type_info *t = reinterpret_cast (p); - return t->__is_pointer_p (); -} - diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h new file mode 100644 index 00000000000..ce897b91f8c --- /dev/null +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -0,0 +1,163 @@ +// -*- C++ -*- Exception handling and frame unwind runtime interface routines. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of GNU CC. +// +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// This is derived from the C++ ABI for IA-64. Where we diverge +// for cross-architecture compatibility are noted with "@@@". + +#ifndef __UNWIND_CXX_H +#define __UNWIND_CXX_H 1 + +// Level 2: C++ ABI + +#include +#include +#include +#include "unwind.h" + +namespace __cxxabiv1 +{ + +// A C++ exception object consists of a header, which is a wrapper around +// an unwind object header with additional C++ specific information, +// followed by the exception object itself. + +struct __cxa_exception +{ + // Manage the exception object itself. + std::type_info *exceptionType; + void (*exceptionDestructor)(void *); + + // The C++ standard has entertaining rules wrt calling set_terminate + // and set_unexpected in the middle of the exception cleanup process. + std::unexpected_handler unexpectedHandler; + std::terminate_handler terminateHandler; + + // The caught exception stack threads through here. + __cxa_exception *nextException; + + // How many nested handlers have caught this exception. A negated + // value is a signal that this object has been rethrown. + int handlerCount; + + // Cache parsed handler data from the personality routine Phase 1 + // for Phase 2 and __cxa_call_unexpected. + int handlerSwitchValue; + const unsigned char *actionRecord; + const unsigned char *languageSpecificData; + void *catchTemp; + void *adjustedPtr; + + // The generic exception header. Must be last. + _Unwind_Exception unwindHeader; +}; + +// Each thread in a C++ program has access to a __cxa_eh_globals object. +struct __cxa_eh_globals +{ + __cxa_exception *caughtExceptions; + unsigned int uncaughtExceptions; +}; + + +// The __cxa_eh_globals for the current thread can be obtained by using +// either of the following functions. The "fast" version assumes at least +// one prior call of __cxa_get_globals has been made from the current +// thread, so no initialization is necessary. +extern "C" __cxa_eh_globals *__cxa_get_globals () throw(); +extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw(); + +// Allocate memory for the exception plus the thown object. +extern "C" void *__cxa_allocate_exception(std::size_t thrown_size) throw(); + +// Free the space allocated for the exception. +extern "C" void __cxa_free_exception(void *thrown_exception) throw(); + +// Throw the exception. +extern "C" void __cxa_throw (void *thrown_exception, + std::type_info *tinfo, + void (*dest) (void *)) + __attribute__((noreturn)); + +// Used to implement exception handlers. +extern "C" void *__cxa_begin_catch (_Unwind_Exception *) throw(); +extern "C" void __cxa_end_catch (); +extern "C" void __cxa_rethrow () __attribute__((noreturn)); + +// These facilitate code generation for recurring situations. +extern "C" void __cxa_bad_cast (); +extern "C" void __cxa_bad_typeid (); + +// @@@ These are not directly specified by the IA-64 C++ ABI. + +// Handles re-checking the exception specification if unexpectedHandler +// throws, and if bad_exception needs to be thrown. Called from the +// compiler. +extern "C" void __cxa_call_unexpected (_Unwind_Exception *) + __attribute__((noreturn)); + +// Invokes given handler, dying appropriately if the user handler was +// so inconsiderate as to return. +extern void __terminate(std::terminate_handler) __attribute__((noreturn)); +extern void __unexpected(std::unexpected_handler) __attribute__((noreturn)); + +// The current installed user handlers. +extern std::terminate_handler __terminate_handler; +extern std::unexpected_handler __unexpected_handler; + +// These are explicitly GNU C++ specific. + +// This is the exception class we report -- "GNUCC++\0". +const _Unwind_Exception_Class __gxx_exception_class += ((((((((_Unwind_Exception_Class) 'G' + << 8 | (_Unwind_Exception_Class) 'N') + << 8 | (_Unwind_Exception_Class) 'U') + << 8 | (_Unwind_Exception_Class) 'C') + << 8 | (_Unwind_Exception_Class) 'C') + << 8 | (_Unwind_Exception_Class) '+') + << 8 | (_Unwind_Exception_Class) '+') + << 8 | (_Unwind_Exception_Class) '\0'); + +// GNU C++ personality routine, Version 0. +extern "C" _Unwind_Reason_Code __gxx_personality_v0 + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +// GNU C++ sjlj personality routine, Version 0. +extern "C" _Unwind_Reason_Code __gxx_personality_sj0 + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +// Acquire the C++ exception header from the C++ object. +static inline __cxa_exception * +__get_exception_header_from_obj (void *ptr) +{ + return reinterpret_cast<__cxa_exception *>(ptr) - 1; +} + +// Acquire the C++ exception header from the generic exception header. +static inline __cxa_exception * +__get_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; +} + +} /* namespace __cxxabiv1 */ + +#endif // __UNWIND_CXX_H diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc index 037d052bae6..5bd8ec8a47b 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -35,7 +35,7 @@ #include #include -#include "exception_support.h" +#include "unwind-cxx.h" namespace __cxxabiv1 { @@ -43,11 +43,21 @@ namespace __cxxabiv1 { struct uncatch_exception { - uncatch_exception () { p = __uncatch_exception (); } - ~uncatch_exception () { __recatch_exception (p); } + uncatch_exception (); + ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } - cp_eh_info *p; + __cxa_exception *p; }; + + uncatch_exception::uncatch_exception () + { + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + + p = globals->caughtExceptions; + p->handlerCount -= 1; + globals->caughtExceptions = p->nextException; + globals->uncaughtExceptions += 1; + } } // Allocate and construct array. diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index c48adc78ade..7d2619e3827 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -120,13 +120,11 @@ OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ # These bits are all figured out from configure. Look in acinclude.m4 # or configure.in to see how they are set. See GLIBCPP_EXPORT_FLAGS # NB: DEBUGFLAGS have to be at the end so that -O2 can be overridden. -CONFIG_CXXFLAGS = \ - @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@ +CONFIG_CXXFLAGS = @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@ # Warning flags to use. -WARN_CXXFLAGS = \ - @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once +WARN_CXXFLAGS = @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once # Use common includes from acinclude.m4/GLIBCPP_EXPORT_INCLUDES @@ -138,133 +136,44 @@ LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ LIBIO_INCLUDES = @LIBIO_INCLUDES@ TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@ -INCLUDES = \ - -nostdinc++ \ - -I$(GLIBCPP_INCLUDE_DIR) $(CSTD_INCLUDES) -I$(top_builddir)/include \ - $(LIBSUPCXX_INCLUDES) $(LIBIO_INCLUDES) $(LIBMATH_INCLUDES) \ - $(TOPLEVEL_INCLUDES) - - -base_headers = \ - bits/cpp_type_traits.h bits/char_traits.h bits/codecvt.h \ - bits/stringfwd.h bits/std_string.h bits/basic_string.h \ - bits/basic_string.tcc \ - bits/generic_shadow.h bits/std_utility.h \ - bits/std_complex.h \ - bits/valarray_array.h bits/valarray_array.tcc bits/valarray_meta.h \ - bits/std_valarray.h bits/mask_array.h bits/slice.h bits/slice_array.h \ - bits/gslice.h bits/gslice_array.h bits/indirect_array.h \ - bits/std_fstream.h bits/std_iomanip.h \ - bits/ios_base.h bits/fpos.h bits/basic_ios.h bits/basic_ios.tcc \ - bits/std_ios.h bits/std_iosfwd.h bits/std_iostream.h \ - bits/std_istream.h bits/istream.tcc bits/std_locale.h \ - bits/fstream.tcc bits/ostream.tcc bits/sbuf_iter.h bits/sstream.tcc \ - bits/std_ostream.h bits/std_sstream.h bits/std_streambuf.h \ - bits/streambuf.tcc bits/basic_file.h \ - bits/locale_facets.h bits/locale_facets.tcc bits/localefwd.h \ - bits/stl_pthread_alloc.h bits/pthread_allocimpl.h \ - bits/stl_threads.h bits/stl_iterator_base.h \ - bits/std_bitset.h bits/std_deque.h bits/std_functional.h \ - bits/std_iterator.h bits/std_list.h \ - bits/std_map.h bits/std_memory.h bits/std_numeric.h \ - bits/std_queue.h bits/std_set.h bits/std_stack.h \ - bits/std_stdexcept.h bits/functexcept.h bits/std_vector.h \ - bits/stl_algo.h bits/stl_algobase.h bits/stl_alloc.h \ - bits/stl_deque.h bits/stl_function.h \ - bits/stl_heap.h bits/stl_iterator.h bits/stl_list.h bits/stl_map.h \ - bits/stl_multimap.h bits/stl_multiset.h bits/stl_numeric.h \ - bits/stl_pair.h bits/stl_queue.h bits/stl_raw_storage_iter.h \ - bits/stl_relops.h bits/stl_set.h \ - bits/stl_stack.h bits/stl_tempbuf.h \ - bits/stl_tree.h bits/stl_uninitialized.h bits/stl_vector.h \ - bits/type_traits.h bits/std_algorithm.h \ - bits/concept_checks.h bits/container_concepts.h \ - bits/sequence_concepts.h bits/stl_construct.h - - -backward_headers = \ - backward/complex.h backward/iomanip.h backward/istream.h \ - backward/ostream.h backward/stream.h backward/streambuf.h \ - backward/algo.h backward/algobase.h backward/alloc.h \ - backward/bvector.h backward/defalloc.h backward/deque.h \ - backward/function.h backward/hash_map.h backward/hash_set.h \ - backward/hashtable.h backward/heap.h backward/iterator.h \ - backward/list.h backward/map.h backward/multimap.h backward/new.h \ - backward/multiset.h backward/pair.h backward/iostream.h \ - backward/rope.h backward/set.h backward/slist.h backward/stack.h \ - backward/tempbuf.h backward/tree.h backward/vector.h \ - backward/fstream.h backward/strstream.h backward/strstream - - -ext_headers = \ - ext/ropeimpl.h ext/stl_rope.h \ - ext/stl_bvector.h ext/stl_hashtable.h ext/stl_hash_fun.h \ - ext/hash_map ext/hash_set ext/rope ext/slist \ - ext/tree ext/bvector - - -c_base_headers = \ - bits/std_cassert.h bits/std_cctype.h bits/std_cerrno.h \ - bits/std_cfloat.h bits/std_climits.h bits/std_clocale.h \ - bits/std_cmath.h bits/std_csetjmp.h bits/std_csignal.h \ - bits/std_cstdarg.h bits/std_cstddef.h bits/std_cstdio.h \ - bits/std_cstdlib.h bits/std_cstring.h bits/std_ctime.h \ - bits/std_cwchar.h bits/std_cwctype.h bits/cmath.tcc - -@GLIBCPP_USE_CSHADOW_TRUE@c_shadow_headers = @GLIBCPP_USE_CSHADOW_TRUE@\ -@GLIBCPP_USE_CSHADOW_TRUE@ assert.h ctype.h errno.h float.h limits.h locale.h math.h setjmp.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ signal.h stdarg.h stddef.h stdio.h stdlib.h string.h time.h wchar.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ wctype.h fcntl.h libio.h iolibio.h libioP.h pthread.h iconv.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ features.h langinfo.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ bits/wrap_libio.h bits/wrap_iolibio.h bits/wrap_libioP.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ bits/wrap_iconv.h bits/wrap_fcntl.h bits/wrap_pthread.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ bits/wrap_features.h bits/wrap_langinfo.h \ -@GLIBCPP_USE_CSHADOW_TRUE@ sys/cdefs.h +INCLUDES = -nostdinc++ -I$(GLIBCPP_INCLUDE_DIR) $(CSTD_INCLUDES) -I$(top_builddir)/include $(LIBSUPCXX_INCLUDES) $(LIBIO_INCLUDES) $(LIBMATH_INCLUDES) $(TOPLEVEL_INCLUDES) + + +base_headers = bits/cpp_type_traits.h bits/char_traits.h bits/codecvt.h bits/stringfwd.h bits/std_string.h bits/basic_string.h bits/basic_string.tcc bits/generic_shadow.h bits/std_utility.h bits/std_complex.h bits/valarray_array.h bits/valarray_array.tcc bits/valarray_meta.h bits/std_valarray.h bits/mask_array.h bits/slice.h bits/slice_array.h bits/gslice.h bits/gslice_array.h bits/indirect_array.h bits/std_fstream.h bits/std_iomanip.h bits/ios_base.h bits/fpos.h bits/basic_ios.h bits/basic_ios.tcc bits/std_ios.h bits/std_iosfwd.h bits/std_iostream.h bits/std_istream.h bits/istream.tcc bits/std_locale.h bits/fstream.tcc bits/ostream.tcc bits/sbuf_iter.h bits/sstream.tcc bits/std_ostream.h bits/std_sstream.h bits/std_streambuf.h bits/streambuf.tcc bits/basic_file.h bits/locale_facets.h bits/locale_facets.tcc bits/localefwd.h bits/stl_pthread_alloc.h bits/pthread_allocimpl.h bits/stl_threads.h bits/stl_iterator_base.h bits/std_bitset.h bits/std_deque.h bits/std_functional.h bits/std_iterator.h bits/std_list.h bits/std_map.h bits/std_memory.h bits/std_numeric.h bits/std_queue.h bits/std_set.h bits/std_stack.h bits/std_stdexcept.h bits/functexcept.h bits/std_vector.h bits/stl_algo.h bits/stl_algobase.h bits/stl_alloc.h bits/stl_deque.h bits/stl_function.h bits/stl_heap.h bits/stl_iterator.h bits/stl_list.h bits/stl_map.h bits/stl_multimap.h bits/stl_multiset.h bits/stl_numeric.h bits/stl_pair.h bits/stl_queue.h bits/stl_raw_storage_iter.h bits/stl_relops.h bits/stl_set.h bits/stl_stack.h bits/stl_tempbuf.h bits/stl_tree.h bits/stl_uninitialized.h bits/stl_vector.h bits/type_traits.h bits/std_algorithm.h bits/concept_checks.h bits/container_concepts.h bits/sequence_concepts.h bits/stl_construct.h + + +backward_headers = backward/complex.h backward/iomanip.h backward/istream.h backward/ostream.h backward/stream.h backward/streambuf.h backward/algo.h backward/algobase.h backward/alloc.h backward/bvector.h backward/defalloc.h backward/deque.h backward/function.h backward/hash_map.h backward/hash_set.h backward/hashtable.h backward/heap.h backward/iterator.h backward/list.h backward/map.h backward/multimap.h backward/new.h backward/multiset.h backward/pair.h backward/iostream.h backward/rope.h backward/set.h backward/slist.h backward/stack.h backward/tempbuf.h backward/tree.h backward/vector.h backward/fstream.h backward/strstream.h backward/strstream + + +ext_headers = ext/ropeimpl.h ext/stl_rope.h ext/stl_bvector.h ext/stl_hashtable.h ext/stl_hash_fun.h ext/hash_map ext/hash_set ext/rope ext/slist ext/tree ext/bvector + + +c_base_headers = bits/std_cassert.h bits/std_cctype.h bits/std_cerrno.h bits/std_cfloat.h bits/std_climits.h bits/std_clocale.h bits/std_cmath.h bits/std_csetjmp.h bits/std_csignal.h bits/std_cstdarg.h bits/std_cstddef.h bits/std_cstdio.h bits/std_cstdlib.h bits/std_cstring.h bits/std_ctime.h bits/std_cwchar.h bits/std_cwctype.h bits/cmath.tcc + +@GLIBCPP_USE_CSHADOW_TRUE@c_shadow_headers = assert.h ctype.h errno.h float.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stddef.h stdio.h stdlib.h string.h time.h wchar.h wctype.h fcntl.h libio.h iolibio.h libioP.h pthread.h iconv.h features.h langinfo.h bits/wrap_libio.h bits/wrap_iolibio.h bits/wrap_libioP.h bits/wrap_iconv.h bits/wrap_fcntl.h bits/wrap_pthread.h bits/wrap_features.h bits/wrap_langinfo.h sys/cdefs.h @GLIBCPP_USE_CSHADOW_FALSE@c_shadow_headers = -std_headers = \ - algorithm bitset complex deque fstream functional \ - iomanip ios iosfwd iostream istream iterator limits list locale \ - map memory numeric ostream queue set sstream stack stdexcept \ - streambuf string utility valarray vector \ - cassert cctype cerrno cfloat climits clocale ciso646 \ - cmath csetjmp csignal cstdarg cstddef cstdio cstdlib \ - cstring ctime cwchar cwctype - -@GLIBCPP_NEED_LIBIO_TRUE@libio_headers = @GLIBCPP_NEED_LIBIO_TRUE@\ -@GLIBCPP_NEED_LIBIO_TRUE@ $(top_srcdir)/libio/_G_config.h $(top_srcdir)/libio/libio.h +std_headers = algorithm bitset complex deque fstream functional iomanip ios iosfwd iostream istream iterator limits list locale map memory numeric ostream queue set sstream stack stdexcept streambuf string utility valarray vector cassert cctype cerrno cfloat climits clocale ciso646 cmath csetjmp csignal cstdarg cstddef cstdio cstdlib cstring ctime cwchar cwctype + +@GLIBCPP_NEED_LIBIO_TRUE@libio_headers = $(top_srcdir)/libio/_G_config.h $(top_srcdir)/libio/libio.h @GLIBCPP_NEED_LIBIO_FALSE@libio_headers = -build_headers = \ - bits/std_limits.h \ - bits/c++config.h bits/c++io.h bits/c++locale.h bits/c++threads.h \ - bits/basic_file_model.h \ - bits/atomicity.h bits/os_defines.h \ - bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h +build_headers = bits/std_limits.h bits/c++config.h bits/c++io.h bits/c++locale.h bits/c++threads.h bits/basic_file_model.h bits/atomicity.h bits/os_defines.h bits/ctype_base.h bits/ctype_noninline.h bits/ctype_inline.h -sources = \ - limitsMEMBERS.cc \ - stdexcept.cc functexcept.cc bitset.cc \ - globals.cc \ - basic_file.cc ios.cc complex_io.cc strstream.cc \ - c++locale.cc locale.cc localename.cc codecvt.cc \ - locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc \ - string-inst.cc wstring-inst.cc +sources = limitsMEMBERS.cc stdexcept.cc functexcept.cc bitset.cc globals.cc basic_file.cc ios.cc complex_io.cc strstream.cc c++locale.cc locale.cc localename.cc codecvt.cc locale-inst.cc stl-inst.cc misc-inst.cc valarray-inst.cc string-inst.cc wstring-inst.cc VPATH = $(top_srcdir) $(top_srcdir)/src $(GLIBCPP_INCLUDE_DIR) $(GLIBCPP_INCLUDE_DIR)/std $(C_INCLUDE_DIR) libstdc___la_SOURCES = $(sources) -libstdc___la_LIBADD = \ - ../libmath/libmath.la @libio_la@ \ - ../libsupc++/libsupc++convenience.la +libstdc___la_LIBADD = ../libmath/libmath.la @libio_la@ ../libsupc++/libsupc++convenience.la libstdc___la_LDFLAGS = -version-info 3:0:0 -lm libstdc___la_DEPENDENCIES = $(libstdc___la_LIBADD) -@GLIBCPP_USE_CSHADOW_TRUE@CSHADOW_H = @GLIBCPP_USE_CSHADOW_TRUE@$(top_builddir)/stamp-cshadow +@GLIBCPP_USE_CSHADOW_TRUE@CSHADOW_H = $(top_builddir)/stamp-cshadow @GLIBCPP_USE_CSHADOW_FALSE@CSHADOW_H = # Check for various configure bits that change where the headers get installed. @@ -283,12 +192,7 @@ c_incdir = @C_INCLUDE_DIR@ # set this option because CONFIG_CXXFLAGS has to be after # OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden # as the occasion call for it. (ie, --enable-debug) -AM_CXXFLAGS = \ - -fno-implicit-templates \ - $(LIBSUPCXX_CXXFLAGS) \ - $(WARN_CXXFLAGS) \ - $(OPTIMIZE_CXXFLAGS) \ - $(CONFIG_CXXFLAGS) +AM_CXXFLAGS = -fno-implicit-templates $(LIBSUPCXX_CXXFLAGS) $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) # libstdc++ libtool notes @@ -309,8 +213,7 @@ AM_CXXFLAGS = \ # correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe # CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to # attempt to infer which configuration to use -LTCXXCOMPILE = $(LIBTOOL) --tag CXX --mode=compile $(CXX) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag CXX --mode=compile $(CXX) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) # 3) We'd have a problem when building the shared libstdc++ object if @@ -319,8 +222,7 @@ LTCXXCOMPILE = $(LIBTOOL) --tag CXX --mode=compile $(CXX) $(INCLUDES) \ # course is problematic at this point. So, we get the top-level # directory to configure libstdc++-v3 to use gcc as the C++ # compilation driver. -CXXLINK = $(LIBTOOL) --tag CXX --mode=link $(CXX) \ - @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@ +CXXLINK = $(LIBTOOL) --tag CXX --mode=link $(CXX) @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@ CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -475,7 +377,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ -- 2.30.2