This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH for exception-handling
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH for exception-handling
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Sun, 19 Sep 1999 09:09:11 -0700
- Organization: CodeSourcery, LLC
Here's a patch to fix the abort in scan_region that occurs with
exception-handling in C++. We're seeing this more, with
-fnew-exceptions, but it appears to have been possible to trigger this
bug even before that was the default.
I've put this in, but someone else's eyes on it wouldn't hurt a bit.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
Sun Sep 19 09:03:40 1999 Mark Mitchell <mark@codesourcery.com>
* rtl.h (insns_safe_to_move_p): New function.
* loop.c (find_and_verify_loops): Use it.
* rtlanal.c (insns_safe_to_move_p): Define it.
Index: testsuite/g++.old-deja/g++.eh/crash1.C
===================================================================
RCS file: crash1.C
diff -N crash1.C
*** /dev/null Sat Dec 5 20:30:03 1998
--- crash1.C Sun Sep 19 09:02:27 1999
***************
*** 0 ****
--- 1,22 ----
+ // Build don't link:
+ // Special g++ Options: -O1 -fno-inline-functions
+
+ struct A
+ {
+ ~A ();
+ };
+
+ bool foo ();
+
+ int i;
+ int j;
+
+ A bar ()
+ {
+ for (i = 0; i < 1; ++i)
+ if (j)
+ {
+ A tmp;
+ return tmp;
+ }
+ }
Index: loop.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/loop.c,v
retrieving revision 1.186
diff -c -p -r1.186 loop.c
*** loop.c 1999/09/14 07:34:59 1.186
--- loop.c 1999/09/19 15:55:42
*************** find_and_verify_loops (f)
*** 2779,2784 ****
--- 2779,2785 ----
{
rtx p;
rtx our_next = next_real_insn (insn);
+ rtx last_insn_to_move = NEXT_INSN (insn);
int dest_loop;
int outer_loop = -1;
*************** find_and_verify_loops (f)
*** 2830,2836 ****
&& INSN_UID (JUMP_LABEL (p)) != 0
&& condjump_p (p)
&& ! simplejump_p (p)
! && next_real_insn (JUMP_LABEL (p)) == our_next)
{
rtx target
= JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
--- 2831,2841 ----
&& INSN_UID (JUMP_LABEL (p)) != 0
&& condjump_p (p)
&& ! simplejump_p (p)
! && next_real_insn (JUMP_LABEL (p)) == our_next
! /* If it's not safe to move the sequence, then we
! mustn't try. */
! && insns_safe_to_move_p (p, NEXT_INSN (insn),
! &last_insn_to_move))
{
rtx target
= JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
*************** find_and_verify_loops (f)
*** 2885,2895 ****
/* Include the BARRIER after INSN and copy the
block after LOC. */
! new_label = squeeze_notes (new_label, NEXT_INSN (insn));
! reorder_insns (new_label, NEXT_INSN (insn), loc);
/* All those insns are now in TARGET_LOOP_NUM. */
! for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
q = NEXT_INSN (q))
uid_loop_num[INSN_UID (q)] = target_loop_num;
--- 2890,2902 ----
/* Include the BARRIER after INSN and copy the
block after LOC. */
! new_label = squeeze_notes (new_label,
! last_insn_to_move);
! reorder_insns (new_label, last_insn_to_move, loc);
/* All those insns are now in TARGET_LOOP_NUM. */
! for (q = new_label;
! q != NEXT_INSN (last_insn_to_move);
q = NEXT_INSN (q))
uid_loop_num[INSN_UID (q)] = target_loop_num;
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.135
diff -c -p -r1.135 rtl.h
*** rtl.h 1999/09/15 23:05:03 1.135
--- rtl.h 1999/09/19 15:55:44
*************** extern int for_each_rtx
*** 1130,1135 ****
--- 1130,1136 ----
extern rtx regno_use_in PROTO((int, rtx));
extern int auto_inc_p PROTO((rtx));
extern void remove_node_from_expr_list PROTO((rtx, rtx *));
+ extern int insns_safe_to_move_p PROTO((rtx, rtx, rtx *));
/* flow.c */
Index: rtlanal.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtlanal.c,v
retrieving revision 1.40
diff -c -p -r1.40 rtlanal.c
*** rtlanal.c 1999/09/03 22:23:11 1.40
--- rtlanal.c 1999/09/19 15:55:45
*************** auto_inc_p (x)
*** 2293,2295 ****
--- 2293,2365 ----
}
return 0;
}
+
+ /* Return 1 if the sequence of instructions beginning with FROM and up
+ to and including TO is safe to move. If NEW_TO is non-NULL, and
+ the sequence is not already safe to move, but can be easily
+ extended to a sequence which is safe, then NEW_TO will point to the
+ end of the extended sequence. */
+
+ int
+ insns_safe_to_move_p (from, to, new_to)
+ rtx from;
+ rtx to;
+ rtx *new_to;
+ {
+ int eh_region_count = 0;
+ int past_to_p = 0;
+ rtx r = from;
+
+ while (r)
+ {
+ if (GET_CODE (r) == NOTE)
+ {
+ switch (NOTE_LINE_NUMBER (r))
+ {
+ case NOTE_INSN_EH_REGION_BEG:
+ ++eh_region_count;
+ break;
+
+ case NOTE_INSN_EH_REGION_END:
+ if (eh_region_count == 0)
+ /* This sequence of instructions contains the end of
+ an exception region, but not he beginning. Moving
+ it will cause chaos. */
+ return 0;
+
+ --eh_region_count;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (past_to_p)
+ /* If we've passed TO, and we see a non-note instruction, we
+ can't extend the sequence to a movable sequence. */
+ return 0;
+
+ if (r == to)
+ {
+ if (!new_to)
+ /* It's OK to move the sequence if there were matched sets of
+ exception region notes. */
+ return eh_region_count == 0;
+
+ past_to_p = 1;
+ }
+
+ /* It's OK to move the sequence if there were matched sets of
+ exception region notes. */
+ if (past_to_p && eh_region_count == 0)
+ {
+ *new_to = r;
+ return 1;
+ }
+
+ /* Go to the next instruction. */
+ r = NEXT_INSN (r);
+ }
+
+ return 0;
+ }