aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/exception.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>1997-11-10 15:03:49 -0500
committerJason Merrill <jason@gcc.gnu.org>1997-11-10 15:03:49 -0500
commitc7ae64f2cc5733e40bfb3ca6a58a63ece97691e3 (patch)
treebcf117ed27d06a44b18a74813ec3d1623001099e /gcc/cp/exception.cc
parent26f578a2286268f9ec2815978264f2647d6516ff (diff)
downloadgcc-c7ae64f2cc5733e40bfb3ca6a58a63ece97691e3.zip
gcc-c7ae64f2cc5733e40bfb3ca6a58a63ece97691e3.tar.gz
gcc-c7ae64f2cc5733e40bfb3ca6a58a63ece97691e3.tar.bz2
stmt.c (expand_decl_cleanup_no_eh): New fn.
* stmt.c (expand_decl_cleanup_no_eh): New fn. * except.c (expand_leftover_cleanups): do_pending_stack_adjust. Complete nested exception support. * except.c (do_pop_exception): Split out... (push_eh_cleanup): From here. Handle the EH region by hand. (expand_start_catch_block): Add a new level for the catch parm. Move the rethrow region outside the two cleanup regions. Protect the initializer for the catch parm with terminate. (expand_end_catch_block): Likewise. End the region for the eh_cleanup. * exception.cc (__cp_pop_exception): Now takes two parms. Handle popping off the middle of the stack. * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR, WITH_CLEANUP_EXPR, and UNSAVE_EXPR. (build_cplus_new): Only wrap CALL_EXPRs. * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around the constructor call. From-SVN: r16419
Diffstat (limited to 'gcc/cp/exception.cc')
-rw-r--r--gcc/cp/exception.cc21
1 files changed, 17 insertions, 4 deletions
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
index 4099d47..2d1ae08 100644
--- a/gcc/cp/exception.cc
+++ b/gcc/cp/exception.cc
@@ -118,12 +118,26 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
}
/* Compiler hook to pop an exception that has been finalized. Used by
- push_eh_cleanup(). */
+ push_eh_cleanup(). P is the info for the exception caught by the
+ current catch block, and HANDLER determines if we've been called from
+ an exception handler; if so, we avoid destroying the object on rethrow. */
extern "C" void
-__cp_pop_exception (void)
+__cp_pop_exception (cp_eh_info *p, bool handler)
{
- cp_eh_info *p = __eh_info;
+ cp_eh_info **q = &__eh_info;
+
+ if (handler && p == *q)
+ return;
+
+ for (; *q; q = &((*q)->next))
+ if (*q == p)
+ break;
+
+ if (! *q)
+ terminate ();
+
+ *q = p->next;
if (p->cleanup)
/* 3 is a magic value for destructors; see build_delete(). */
@@ -133,7 +147,6 @@ __cp_pop_exception (void)
else
delete p->value;
- __eh_info = p->next;
delete p;
}