except.c (build_throw): Wrap the initialization of the exception object in a MUST_NOT...
authorJason Merrill <jason@redhat.com>
Sun, 22 Apr 2001 23:50:06 +0000 (19:50 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 22 Apr 2001 23:50:06 +0000 (19:50 -0400)
        * except.c (build_throw): Wrap the initialization of the exception
        object in a MUST_NOT_THROW_EXPR.
        (do_free_exception): #if 0.

From-SVN: r41494

gcc/cp/ChangeLog
gcc/cp/except.c
gcc/testsuite/g++.old-deja/g++.eh/terminate1.C [new file with mode: 0644]

index f0f3204..d827330 100644 (file)
@@ -1,3 +1,9 @@
+2001-04-23  Jason Merrill  <jason_merrill@redhat.com>
+
+       * except.c (build_throw): Wrap the initialization of the exception
+       object in a MUST_NOT_THROW_EXPR.
+       (do_free_exception): #if 0.
+
 2001-04-20  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (finish_enum): Change prototype.
index 600a21a..c68ea40 100644 (file)
@@ -46,7 +46,6 @@ static bool decl_is_java_type PARAMS ((tree decl, int err));
 static void choose_personality_routine PARAMS ((bool));
 static void initialize_handler_parm PARAMS ((tree, tree));
 static tree do_allocate_exception PARAMS ((tree));
-static tree do_free_exception PARAMS ((tree));
 static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
 static bool is_admissible_throw_operand PARAMS ((tree));
 static int can_convert_eh PARAMS ((tree, tree));
@@ -504,8 +503,9 @@ do_allocate_exception (type)
                                             NULL_TREE));
 }
 
-/* Call __cxa_free_exception from a cleanup.  This is invoked when
-   a constructor for a thrown object throws.  */
+#if 0
+/* Call __cxa_free_exception from a cleanup.  This is never invoked
+   directly.  */
 
 static tree
 do_free_exception (ptr)
@@ -525,6 +525,7 @@ do_free_exception (ptr)
 
   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
 }
+#endif
 
 /* Build a throw expression.  */
 
@@ -573,7 +574,6 @@ build_throw (exp)
       tree cleanup;
       tree stmt_expr;
       tree compound_stmt;
-      tree try_block;
       tree object, ptr;
       tree tmp;
 
@@ -645,15 +645,12 @@ build_throw (exp)
       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
       object = build_indirect_ref (object, NULL_PTR);
 
-      try_block = begin_try_block ();
-
       exp = build_modify_expr (object, INIT_EXPR, exp);
       if (exp == error_mark_node)
        error ("  in thrown expression");
 
+      exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
       finish_expr_stmt (exp);
-      finish_cleanup_try_block (try_block);
-      finish_cleanup (do_free_exception (ptr), try_block);
 
       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
 
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/terminate1.C b/gcc/testsuite/g++.old-deja/g++.eh/terminate1.C
new file mode 100644 (file)
index 0000000..9526041
--- /dev/null
@@ -0,0 +1,27 @@
+// Test that an exception thrown out of the constructor for the exception
+// object (i.e. "after completing evaluation of the expression to be thrown
+// but before the exception is caught") causes us to call terminate.
+
+#include <exception>
+#include <cstdlib>
+
+void my_terminate ()
+{
+  std::exit (0);
+}
+
+struct A
+{
+  A () {}
+  A (const A&) { throw 1; }
+};
+
+int main (void)
+{
+  std::set_terminate (my_terminate);
+
+  A a;
+  try { throw a; }
+  catch (...) {}
+  return 1;
+}