aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1997-11-25 06:14:48 +0000
committerJason Merrill <jason@gcc.gnu.org>1997-11-25 01:14:48 -0500
commit20b9016983fc3fda1ff9f8262b2b428f7a689ea3 (patch)
tree188a0e6b28b848caa1011c2fa6c43434f59efa15
parentc77289885d7b658a980738069be7979c3429ef9b (diff)
downloadgcc-20b9016983fc3fda1ff9f8262b2b428f7a689ea3.zip
gcc-20b9016983fc3fda1ff9f8262b2b428f7a689ea3.tar.gz
gcc-20b9016983fc3fda1ff9f8262b2b428f7a689ea3.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/except.c19
-rw-r--r--gcc/cp/exception.cc18
3 files changed, 37 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 88c9d2e..ad1788b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index bd26053..ff7a45b 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 2807118..9c87670 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