Patchwork C++ PATCH to exception-specification of implicitly declared constructors

login
register
mail settings
Submitter Jason Merrill
Date March 5, 2012, 6:08 p.m.
Message ID <4F550103.7020803@redhat.com>
Download mbox | patch
Permalink /patch/144735/
State New
Headers show

Comments

Jason Merrill - March 5, 2012, 6:08 p.m.
In a defaulted constructor, the destructors used for subobject cleanups 
affect whether or not the constructor is deleted.  But discussion in 
Kona pointed out that they should not affect the 
exception-specification, since if one of those cleanups throws an 
exception then it's a double-fault, and we call terminate.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit e5c23605aabc4b96d32facb9d13d469ac3997542
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Feb 9 10:34:26 2012 -1000

    	* method.c (synthesized_method_walk): Cleanups don't affect the EH
    	spec either.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index cf2a713..0718916 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1272,8 +1272,11 @@  synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
 	  rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
 				  NULL_TREE, flags, complain);
 	  /* Note that we don't pass down trivial_p; the subobject
-	     destructors don't affect triviality of the constructor.  */
-	  process_subob_fn (rval, false, spec_p, NULL,
+	     destructors don't affect triviality of the constructor.  Nor
+	     do they affect constexpr-ness (a constant expression doesn't
+	     throw) or exception-specification (a throw from one of the
+	     dtors would be a double-fault).  */
+	  process_subob_fn (rval, false, NULL, NULL,
 			    deleted_p, NULL, NULL,
 			    basetype);
 	}
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit13.C b/gcc/testsuite/g++.dg/cpp0x/implicit13.C
new file mode 100644
index 0000000..96bc770
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/implicit13.C
@@ -0,0 +1,24 @@ 
+// Make sure that A's destructor doesn't affect constexpr
+// or exception-spec on D's default constructor.
+// { dg-do compile { target c++11 } }
+
+struct A {
+  constexpr A() noexcept: i(0) { }
+  int i;
+  ~A() noexcept(false);
+};
+
+struct B: A { };
+
+// Should get static initialization, so no constructor call.
+// { dg-final { scan-assembler-not "_ZN1BC1Ev" } }
+B b;
+
+struct C { C() noexcept; ~C(); };
+struct D: C { };
+extern D d;
+
+void *operator new(__SIZE_TYPE__, void*) noexcept;
+
+#define SA(X) static_assert((X),#X)
+SA(noexcept(new (&d) D));