]> gcc.gnu.org Git - gcc.git/commitdiff
exception.cc (struct cp_eh_info): Add handlers field.
authorJason Merrill <jason@yorick.cygnus.com>
Tue, 25 Nov 1997 06:14:48 +0000 (06:14 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 25 Nov 1997 06:14:48 +0000 (01:14 -0500)
* 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
gcc/cp/except.c
gcc/cp/exception.cc

index 88c9d2edac02fea728924c4cb6d1df3ca5374198..ad1788b304e1c8000e7c246060e83621709523e9 100644 (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.
index bd26053dfcef3d343a828eb348d4b6db5ab6e40a..ff7a45b94a36ea46960ca7fbedd9fbf9c2adfb5d 100644 (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 ();
index 28071183c0f59180a61deb09e3d2147b4a66b12d..9c876700574390380296641c4644993fe0f26c46 100644 (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
This page took 0.079004 seconds and 5 git commands to generate.