Commit 20b90169 by Jason Merrill Committed by Jason Merrill

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
parent c7728988
Mon Nov 24 12:15:55 1997 Jason Merrill <jason@yorick.cygnus.com>
* 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 <jason@yorick.cygnus.com> Fri Nov 21 12:22:07 1997 Jason Merrill <jason@yorick.cygnus.com>
* except.c (expand_start_eh_spec): Use the try/catch code. * except.c (expand_start_eh_spec): Use the try/catch code.
......
...@@ -319,7 +319,7 @@ call_eh_info () ...@@ -319,7 +319,7 @@ call_eh_info ()
fn = IDENTIFIER_GLOBAL_VALUE (fn); fn = IDENTIFIER_GLOBAL_VALUE (fn);
else else
{ {
tree t, fields[5]; tree t, fields[6];
/* Declare cp_eh_info * __cp_exception_info (void), /* Declare cp_eh_info * __cp_exception_info (void),
as defined in exception.cc. */ as defined in exception.cc. */
...@@ -342,9 +342,11 @@ call_eh_info () ...@@ -342,9 +342,11 @@ call_eh_info ()
boolean_type_node); boolean_type_node);
fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"), fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"),
build_pointer_type (t)); 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 /* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */ 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); t = build_pointer_type (t);
/* And now the function. */ /* And now the function. */
...@@ -417,6 +419,16 @@ get_eh_caught () ...@@ -417,6 +419,16 @@ get_eh_caught ()
NULL_TREE, 0); 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 /* Build a type value for use at runtime for a type that is matched
against by the exception handling system. */ against by the exception handling system. */
...@@ -514,6 +526,9 @@ push_eh_cleanup () ...@@ -514,6 +526,9 @@ push_eh_cleanup ()
expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node)); expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node));
resume_momentary (yes); 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 /* We don't destroy the exception object on rethrow, so we can't use
the normal cleanup mechanism for it. */ the normal cleanup mechanism for it. */
expand_eh_region_start (); expand_eh_region_start ();
......
...@@ -75,7 +75,11 @@ unexpected () ...@@ -75,7 +75,11 @@ unexpected ()
} }
/* C++-specific state about the current exception. /* 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 struct cp_eh_info
{ {
...@@ -84,6 +88,7 @@ struct cp_eh_info ...@@ -84,6 +88,7 @@ struct cp_eh_info
void (*cleanup)(void *, int); void (*cleanup)(void *, int);
bool caught; bool caught;
cp_eh_info *next; cp_eh_info *next;
long handlers;
}; };
/* Language-specific EH info pointer, defined in libgcc2. */ /* Language-specific EH info pointer, defined in libgcc2. */
...@@ -113,6 +118,7 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int)) ...@@ -113,6 +118,7 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
p->value = value; p->value = value;
p->type = type; p->type = type;
p->cleanup = cleanup; p->cleanup = cleanup;
p->handlers = 0;
p->caught = false; p->caught = false;
p->next = __eh_info; p->next = __eh_info;
__eh_info = p; __eh_info = p;
...@@ -128,7 +134,9 @@ __cp_pop_exception (cp_eh_info *p, bool handler) ...@@ -128,7 +134,9 @@ __cp_pop_exception (cp_eh_info *p, bool handler)
{ {
cp_eh_info **q = &__eh_info; cp_eh_info **q = &__eh_info;
if (handler && p == *q) --p->handlers;
if (p->handlers > 0 || (handler && p == *q))
return; return;
for (; *q; q = &((*q)->next)) for (; *q; q = &((*q)->next))
...@@ -220,12 +228,6 @@ __throw_bad_typeid (void) ...@@ -220,12 +228,6 @@ __throw_bad_typeid (void)
throw bad_typeid (); throw bad_typeid ();
} }
extern "C" void
__throw_bad_exception (void)
{
throw bad_exception ();
}
/* Has the current exception been caught? */ /* Has the current exception been caught? */
bool bool
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment