(C++) rethrow patch

Jason Merrill jason@cygnus.com
Fri Jun 2 19:19:00 GMT 2000


This patch fixes g++.eh/rethrow6.C, a bizarre corner case involving
rethrowing an exception between the throw and catch of another
exception.  This case is, though I didn't realize it before, the
reason for leaving uncaught exceptions off the EH stack in the new ABI.

2000-06-02  Jason Merrill  <jason@casey.soma.redhat.com>

	* exception.cc (__cp_pop_exception): If we aren't popping or
	rethrowing, push down past any uncaught exceptions.
	(__uncatch_exception): Rethrow the currently handled exception.
	Move it to the top of the exception stack.

Index: exception.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/exception.cc,v
retrieving revision 1.33
diff -c -p -r1.33 exception.cc
*** exception.cc	2000/05/02 01:25:15	1.33
--- exception.cc	2000/06/03 02:16:47
*************** __cp_push_exception (void *value, void *
*** 247,263 ****
  extern "C" void
  __cp_pop_exception (cp_eh_info *p)
  {
!   cp_eh_info **q = __get_eh_info ();
  
    --p->handlers;
  
!   /* Don't really pop if there are still active handlers for our exception,
!      or if our exception is being rethrown (i.e. if the active exception is
!      our exception and it is uncaught).  */
!   if (p->handlers != 0
!       || (p == *q && !p->caught))
      return;
  
    for (; *q; q = &((*q)->next))
      if (*q == p)
        break;
--- 247,283 ----
  extern "C" void
  __cp_pop_exception (cp_eh_info *p)
  {
!   cp_eh_info **stack = __get_eh_info ();
!   cp_eh_info **q = stack;
  
    --p->handlers;
  
!   /* Do nothing if our exception is being rethrown (i.e. if the active
!      exception is our exception and it is uncaught).  */
!   if (p == *q && !p->caught)
      return;
  
+   /* Don't really pop if there are still active handlers for our exception;
+      rather, push it down past any uncaught exceptions.  */
+   if (p->handlers != 0)
+     {
+       if (p == *q && p->next && !p->next->caught)
+ 	{
+ 	  q = &(p->next);
+ 	  while (1)
+ 	    {
+ 	      if (*q == 0 || (*q)->caught)
+ 		break;
+ 
+ 	      q = &((*q)->next);
+ 	    }
+ 	  *stack = p->next;
+ 	  p->next = *q;
+ 	  *q = p;
+ 	}
+       return;
+     }
+ 
    for (; *q; q = &((*q)->next))
      if (*q == p)
        break;
*************** __cp_pop_exception (cp_eh_info *p)
*** 277,288 ****
    __eh_free (p);
  }
  
  extern "C" void
  __uncatch_exception (void)
  {
!   cp_eh_info *p = CP_EH_INFO;
!   if (p == 0)
!     terminate ();
    p->caught = false;
  }
  
--- 297,331 ----
    __eh_free (p);
  }
  
+ /* We're doing a rethrow.  Find the currently handled exception, mark it
+    uncaught, and move it to the top of the EH stack.  */
+ 
  extern "C" void
  __uncatch_exception (void)
  {
!   cp_eh_info **stack = __get_eh_info ();
!   cp_eh_info **q = stack;
!   cp_eh_info *p;
! 
!   while (1)
!     {
!       p = *q;
! 
!       if (p == 0)
! 	terminate ();
!       if (p->caught)
! 	break;
! 
!       q = &(p->next);
!     }
! 
!   if (q != stack)
!     {
!       *q = p->next;
!       p->next = *stack;
!       *stack = p;
!     }
! 
    p->caught = false;
  }
  


More information about the Gcc-patches mailing list