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
This commit is contained in:
Jason Merrill 1997-11-25 06:14:48 +00:00 committed by Jason Merrill
parent c77289885d
commit 20b9016983
3 changed files with 37 additions and 10 deletions

View File

@ -1,3 +1,13 @@
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>
* except.c (expand_start_eh_spec): Use the try/catch code.

View File

@ -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 ();

View File

@ -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