This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH for exception-handling



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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]