From: Ulrich Weigand Date: Sat, 22 Jan 2011 21:24:54 +0000 (+0000) Subject: re PR middle-end/47401 (Support for must-not-throw regions with SJLJ exceptions broken) X-Git-Tag: releases/gcc-4.6.0~1050 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0cecee061e9f6a049703683969b9933f0c8fb07c;p=thirdparty%2Fgcc.git re PR middle-end/47401 (Support for must-not-throw regions with SJLJ exceptions broken) PR middle-end/47401 * except.c (sjlj_assign_call_site_values): Move setting the crtl->uses_eh_lsda flag to ... (sjlj_mark_call_sites): ... here. (sjlj_emit_function_enter): Support NULL dispatch label. (sjlj_build_landing_pads): In a function with no landing pads that still has must-not-throw regions, generate code to register a personality function with empty LSDA. From-SVN: r169134 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1dde632ba5b0..df4658b3fe04 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2011-01-22 Ulrich Weigand + + PR middle-end/47401 + * except.c (sjlj_assign_call_site_values): Move setting the + crtl->uses_eh_lsda flag to ... + (sjlj_mark_call_sites): ... here. + (sjlj_emit_function_enter): Support NULL dispatch label. + (sjlj_build_landing_pads): In a function with no landing pads + that still has must-not-throw regions, generate code to register + a personality function with empty LSDA. + 2011-01-21 Richard Henderson * config/rx/rx.c (TARGET_FLAGS_REGNUM): New. diff --git a/gcc/except.c b/gcc/except.c index 66bf41005a6a..251a5501462a 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -998,8 +998,6 @@ sjlj_assign_call_site_values (void) /* First: build the action table. */ action = collect_one_action_chain (ar_hash, lp->region); - if (action != -1) - crtl->uses_eh_lsda = 1; /* Next: assign call-site values. If dwarf2 terms, this would be the region number assigned by convert_to_eh_region_ranges, but @@ -1065,6 +1063,9 @@ sjlj_mark_call_sites (void) this_call_site = 0; } + if (this_call_site != -1) + crtl->uses_eh_lsda = 1; + if (this_call_site == last_call_site) continue; @@ -1119,27 +1120,30 @@ sjlj_emit_function_enter (rtx dispatch_label) else emit_move_insn (mem, const0_rtx); + if (dispatch_label) + { #ifdef DONT_USE_BUILTIN_SETJMP - { - rtx x, last; - x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE, - TYPE_MODE (integer_type_node), 1, - plus_constant (XEXP (fc, 0), - sjlj_fc_jbuf_ofs), Pmode); - - emit_cmp_and_jump_insns (x, const0_rtx, NE, 0, - TYPE_MODE (integer_type_node), 0, dispatch_label); - last = get_last_insn (); - if (JUMP_P (last) && any_condjump_p (last)) - { - gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); - add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100)); - } - } -#else - expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs), + rtx x, last; + x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE, + TYPE_MODE (integer_type_node), 1, + plus_constant (XEXP (fc, 0), + sjlj_fc_jbuf_ofs), Pmode); + + emit_cmp_and_jump_insns (x, const0_rtx, NE, 0, + TYPE_MODE (integer_type_node), 0, dispatch_label); + last = get_last_insn (); + if (JUMP_P (last) && any_condjump_p (last)) + { + gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); + add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100)); + } +#else + expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), + sjlj_fc_jbuf_ofs), + dispatch_label); #endif + } emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode, 1, XEXP (fc, 0), Pmode); @@ -1363,6 +1367,23 @@ sjlj_build_landing_pads (void) sjlj_emit_function_exit (); } + /* If we do not have any landing pads, we may still need to register a + personality routine and (empty) LSDA to handle must-not-throw regions. */ + else if (function_needs_eh_personality (cfun) != eh_personality_none) + { + int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node, + TYPE_MODE (sjlj_fc_type_node), + TYPE_ALIGN (sjlj_fc_type_node)); + crtl->eh.sjlj_fc + = assign_stack_local (TYPE_MODE (sjlj_fc_type_node), + int_size_in_bytes (sjlj_fc_type_node), + align); + + sjlj_mark_call_sites (); + sjlj_emit_function_enter (NULL_RTX); + sjlj_emit_function_exit (); + } + VEC_free (int, heap, sjlj_lp_call_site_index); }