]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
flow.c (find_basic_blocks): Handle cfg issues for rethrows and nested exceptions...
authorJeffrey A Law <law@cygnus.com>
Fri, 28 Nov 1997 03:05:02 +0000 (03:05 +0000)
committerJeff Law <law@gcc.gnu.org>
Fri, 28 Nov 1997 03:05:02 +0000 (20:05 -0700)
        * flow.c (find_basic_blocks): Handle cfg issues for rethrows and
        nested exceptions correctly.

From-SVN: r16811

gcc/ChangeLog
gcc/flow.c

index acaa173f91b7952ce3752aacf76582746cb3eb81..ea39d3810ea1a51657c7e9bec5d8116c0e95b149 100644 (file)
@@ -1,4 +1,7 @@
 Thu Nov 27 12:20:19 1997  Jeffrey A Law  (law@cygnus.com)
+       
+       * flow.c (find_basic_blocks): Handle cfg issues for rethrows and
+       nested exceptions correctly.
 
        * unroll.c (find_splittable_givs): Don't split givs with a dest_reg
        that was created by loop.
index b98008267dc9e91a1b415817aa79e698f0cff049..66374163e8bfc6ea9eca07976b4e3e284ee20bf2 100644 (file)
@@ -472,10 +472,15 @@ find_basic_blocks (f, nonlocal_label_list)
       /* If we encounter a CALL_INSN, note which exception handler it
         might pass control to.
 
+        Because we do rethrows by loading the address of a label into
+        __eh_pc and throwing, we need to treat labels as potentially
+        jumping to exception handlers.
+
         If doing asynchronous exceptions, record the active EH handler
         for every insn, since most insns can throw.  */
       else if (eh_note
               && (asynchronous_exceptions
+                  || code == CODE_LABEL
                   || (GET_CODE (insn) == CALL_INSN
                       && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))))
        active_eh_handler[INSN_UID (insn)] = XEXP (eh_note, 0);
@@ -569,7 +574,11 @@ find_basic_blocks (f, nonlocal_label_list)
                           associated insns aren't marked dead, so we make
                           the block in question live and create an edge from
                           this insn to the label.  This is not strictly
-                          correct, but it is close enough for now.  */
+                          correct, but it is close enough for now.
+
+                          We also need to mark the CODE_LABEL as reaching
+                          its exception handler for nested exceptions to
+                          to work.  */
                        for (note = REG_NOTES (insn);
                             note;
                             note = XEXP (note, 1))
@@ -581,6 +590,14 @@ find_basic_blocks (f, nonlocal_label_list)
                                mark_label_ref (gen_rtx (LABEL_REF,
                                                         VOIDmode, x),
                                                insn, 0);
+
+                               /* If the CODE_LABEL has an active exception
+                                  handler, then make an edge to the exception
+                                  handler from this insn.  */
+                               if (active_eh_handler[INSN_UID (x)])
+                                 mark_label_ref (gen_rtx (LABEL_REF, VOIDmode,
+                                                          active_eh_handler[INSN_UID (x)]),
+                                                 insn, 0);
                              }
                          }