From 20b9016983fc3fda1ff9f8262b2b428f7a689ea3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 25 Nov 1997 06:14:48 +0000 Subject: [PATCH] exception.cc (struct cp_eh_info): Add handlers field. * exception.cc (struct cp_eh_info): Add handlers field. (__cp_push_exception): Initialize it. (__cp_pop_exception): Decrement it. Don't pop unless it's 0. (__throw_bad_exception): Remove. * except.c (call_eh_info): Add handlers field. (get_eh_handlers): New fn. (push_eh_cleanup): Increment handlers. Fixes P15031.C, rethrow[45].C From-SVN: r16694 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/except.c | 19 +++++++++++++++++-- gcc/cp/exception.cc | 18 ++++++++++-------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 88c9d2edac02..ad1788b304e1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +Mon Nov 24 12:15:55 1997 Jason Merrill + + * exception.cc (struct cp_eh_info): Add handlers field. + (__cp_push_exception): Initialize it. + (__cp_pop_exception): Decrement it. Don't pop unless it's 0. + (__throw_bad_exception): Remove. + * except.c (call_eh_info): Add handlers field. + (get_eh_handlers): New fn. + (push_eh_cleanup): Increment handlers. + Fri Nov 21 12:22:07 1997 Jason Merrill * except.c (expand_start_eh_spec): Use the try/catch code. diff --git a/gcc/cp/except.c b/gcc/cp/except.c index bd26053dfcef..ff7a45b94a36 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -319,7 +319,7 @@ call_eh_info () fn = IDENTIFIER_GLOBAL_VALUE (fn); else { - tree t, fields[5]; + tree t, fields[6]; /* Declare cp_eh_info * __cp_exception_info (void), as defined in exception.cc. */ @@ -342,9 +342,11 @@ call_eh_info () boolean_type_node); fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"), build_pointer_type (t)); + fields[5] = build_lang_field_decl + (FIELD_DECL, get_identifier ("handlers"), long_integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ - finish_builtin_type (t, "cp_eh_info", fields, 4, ptr_type_node); + finish_builtin_type (t, "cp_eh_info", fields, 5, ptr_type_node); t = build_pointer_type (t); /* And now the function. */ @@ -417,6 +419,16 @@ get_eh_caught () NULL_TREE, 0); } +/* Returns a reference to whether or not the current exception + has been caught. */ + +static tree +get_eh_handlers () +{ + return build_component_ref (get_eh_info (), get_identifier ("handlers"), + NULL_TREE, 0); +} + /* Build a type value for use at runtime for a type that is matched against by the exception handling system. */ @@ -514,6 +526,9 @@ push_eh_cleanup () expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node)); resume_momentary (yes); + expand_expr (build_unary_op (PREINCREMENT_EXPR, get_eh_handlers (), 1), + const0_rtx, VOIDmode, EXPAND_NORMAL); + /* We don't destroy the exception object on rethrow, so we can't use the normal cleanup mechanism for it. */ expand_eh_region_start (); diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc index 28071183c0f5..9c8767005743 100644 --- a/gcc/cp/exception.cc +++ b/gcc/cp/exception.cc @@ -75,7 +75,11 @@ unexpected () } /* C++-specific state about the current exception. - This must match init_exception_processing(). */ + This must match init_exception_processing(). + + Note that handlers and caught are not redundant; when rethrown, an + exception can have multiple active handlers and still be considered + uncaught. */ struct cp_eh_info { @@ -84,6 +88,7 @@ struct cp_eh_info void (*cleanup)(void *, int); bool caught; cp_eh_info *next; + long handlers; }; /* Language-specific EH info pointer, defined in libgcc2. */ @@ -113,6 +118,7 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int)) p->value = value; p->type = type; p->cleanup = cleanup; + p->handlers = 0; p->caught = false; p->next = __eh_info; __eh_info = p; @@ -128,7 +134,9 @@ __cp_pop_exception (cp_eh_info *p, bool handler) { cp_eh_info **q = &__eh_info; - if (handler && p == *q) + --p->handlers; + + if (p->handlers > 0 || (handler && p == *q)) return; for (; *q; q = &((*q)->next)) @@ -220,12 +228,6 @@ __throw_bad_typeid (void) throw bad_typeid (); } -extern "C" void -__throw_bad_exception (void) -{ - throw bad_exception (); -} - /* Has the current exception been caught? */ bool