]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/13944 (exception in constructor of a class to be thrown is not caught)
authorJason Merrill <jason@redhat.com>
Wed, 3 Mar 2004 07:40:31 +0000 (02:40 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 3 Mar 2004 07:40:31 +0000 (02:40 -0500)
        PR c++/13944
        * except.c (do_free_exception): Remove #if 0 wrapper.
        (build_throw): Use it if we elide a copy into the exception object.

From-SVN: r78823

gcc/cp/ChangeLog
gcc/cp/except.c

index 0ee0b2182f2734d0fbe751653beda31d289a3eec..cfd1a6ba4294cdfc11b3c41df962a3f9ee93befa 100644 (file)
@@ -1,3 +1,9 @@
+2004-02-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/13944
+       * except.c (do_free_exception): Remove #if 0 wrapper.
+       (build_throw): Use it if we elide a copy into the exception object.
+
 2004-03-01  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * decl.c (current_binding_level): Define as an lvalue.
index 747cc1aaef692feb3387c2324cf9f1a01833feaa..6b32a5bd08dd89c8d2f6e89b918e4576111cadb1 100644 (file)
@@ -511,9 +511,7 @@ do_allocate_exception (type)
                                             NULL_TREE));
 }
 
-#if 0
-/* Call __cxa_free_exception from a cleanup.  This is never invoked
-   directly, but see the comment for stabilize_throw_expr.  */
+/* Call __cxa_free_exception from a cleanup.  */
 
 static tree
 do_free_exception (ptr)
@@ -533,7 +531,6 @@ do_free_exception (ptr)
 
   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
 }
-#endif
 
 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
    Called from build_throw via walk_tree_without_duplicates.  */
@@ -669,6 +666,7 @@ build_throw (exp)
       tree object, ptr;
       tree tmp;
       tree temp_expr, allocate_expr;
+      bool elided;
 
       fn = get_identifier ("__cxa_throw");
       if (IDENTIFIER_GLOBAL_VALUE (fn))
@@ -723,6 +721,8 @@ build_throw (exp)
       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
       object = build_indirect_ref (object, NULL);
 
+      elided = (TREE_CODE (exp) == TARGET_EXPR);
+
       /* And initialize the exception object.  */
       exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
       if (exp == error_mark_node)
@@ -731,7 +731,11 @@ build_throw (exp)
          return error_mark_node;
        }
 
-      exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
+      if (elided)
+       exp = build (TRY_CATCH_EXPR, void_type_node, exp,
+                    do_free_exception (ptr));
+      else
+       exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
       /* Prepend the allocation.  */
       exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
       if (temp_expr != void_zero_node)