From b55e00bd69ae2e15ce00f33759e20747d21f3fb6 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 25 Nov 1997 19:34:14 +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. From-SVN: r16699 --- 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 8a5a8b37d225..ca8fb2c0e8ce 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_catch_block): We only need the rethrow diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 5c2344d43d79..4477736b82c2 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -318,7 +318,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. */ @@ -341,9 +341,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. */ @@ -416,6 +418,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. */ @@ -513,6 +525,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 2d1ae0812470..caaf58922826 100644 --- a/gcc/cp/exception.cc +++ b/gcc/cp/exception.cc @@ -74,7 +74,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 { @@ -83,6 +87,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. */ @@ -112,6 +117,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; @@ -127,7 +133,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)) @@ -171,12 +179,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 -- 2.47.2