This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) rethrow patch
- To: gcc-patches at gcc dot gnu dot org
- Subject: (C++) rethrow patch
- From: Jason Merrill <jason at cygnus dot com>
- Date: Fri, 2 Jun 2000 19:19:18 -0700
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;
}