]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/47401 (Support for must-not-throw regions with SJLJ exceptions broken)
authorUlrich Weigand <uweigand@de.ibm.com>
Sat, 22 Jan 2011 21:24:54 +0000 (21:24 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sat, 22 Jan 2011 21:24:54 +0000 (21:24 +0000)
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

gcc/ChangeLog
gcc/except.c

index 1dde632ba5b0af8c99861dfd4b0915055aa968de..df4658b3fe046be90b75838eb8553836fcc52374 100644 (file)
@@ -1,3 +1,14 @@
+2011-01-22  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       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  <rth@redhat.com>
 
        * config/rx/rx.c (TARGET_FLAGS_REGNUM): New.
index 66bf41005a6a143499099e582c0831dbdda7028f..251a5501462a9271e520fb0d38589c3b35713065 100644 (file)
@@ -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);
 }