This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to exception-specification of implicitly declared constructors
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 05 Mar 2012 13:08:03 -0500
- Subject: C++ PATCH to exception-specification of implicitly declared constructors
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.
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));