This patch implements the proposed resolution for core issue 1191: base destructors do not affect the triviality of derived constructors, but they do affect the exception specification and deletedness.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 15e4a01c978314724435064f20c373abf7a1bf8c
Author: Jason Merrill <ja...@redhat.com>
Date:   Sun Jan 23 17:52:44 2011 -0500

        Core 1191
        * method.c (synthezized_method_walk): Cleanups don't affect the
        triviality of a constructor, but do affect deletion and exception
        specification.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d70da95..0366988 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1080,14 +1080,9 @@ synthesized_method_walk (tree ctype, 
special_function_kind sfk, bool const_p,
   tsubst_flags_t complain;
   const char *msg;
   bool ctor_p;
-  tree cleanup_spec;
-  bool cleanup_trivial = true;
-  bool cleanup_deleted = false;
 
-  cleanup_spec
-    = (cxx_dialect >= cxx0x ? noexcept_true_spec : empty_except_spec);
   if (spec_p)
-    *spec_p = cleanup_spec;
+    *spec_p = (cxx_dialect >= cxx0x ? noexcept_true_spec : empty_except_spec);
 
   if (deleted_p)
     {
@@ -1228,8 +1223,10 @@ synthesized_method_walk (tree ctype, 
special_function_kind sfk, bool const_p,
             destructors for cleanup of partially constructed objects.  */
          rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
                                  NULL_TREE, flags, complain);
-         process_subob_fn (rval, false, &cleanup_spec, &cleanup_trivial,
-                           &cleanup_deleted, NULL, NULL,
+         /* 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,
+                           deleted_p, NULL, NULL,
                            basetype);
        }
 
@@ -1275,8 +1272,8 @@ 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);
-             process_subob_fn (rval, false, &cleanup_spec, &cleanup_trivial,
-                               &cleanup_deleted, NULL, NULL,
+             process_subob_fn (rval, false, spec_p, NULL,
+                               deleted_p, NULL, NULL,
                                basetype);
            }
        }
@@ -1295,23 +1292,14 @@ synthesized_method_walk (tree ctype, 
special_function_kind sfk, bool const_p,
   if (ctor_p)
     walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier,
                       sfk_destructor, TYPE_UNQUALIFIED, false,
-                      false, false, &cleanup_spec, &cleanup_trivial,
-                      &cleanup_deleted, NULL,
+                      false, false, spec_p, NULL,
+                      deleted_p, NULL,
                       NULL, flags, complain);
 
   pop_scope (scope);
 
   --cp_unevaluated_operand;
   --c_inhibit_evaluation_warnings;
-
-  /* If the constructor isn't trivial, consider the subobject cleanups.  */
-  if (ctor_p && trivial_p && !*trivial_p)
-    {
-      if (deleted_p && cleanup_deleted)
-       *deleted_p = true;
-      if (spec_p)
-       *spec_p = merge_exception_specifiers (*spec_p, cleanup_spec);
-    }
 }
 
 /* DECL is a deleted function.  If it's implicitly deleted, explain why and
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit11.C 
b/gcc/testsuite/g++.dg/cpp0x/implicit11.C
new file mode 100644
index 0000000..7ec8e95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/implicit11.C
@@ -0,0 +1,17 @@
+// Test that we consider base dtors in determining whether
+// a derived ctor is deleted even if the ctor is trivial.
+// { dg-options -std=c++0x }
+
+struct A
+{
+  ~A() = delete;               // { dg-error "declared here" }
+};
+
+struct B: A { };               // { dg-error "deleted" }
+
+extern B eb;
+int main()
+{
+  B* b1 = new B;               // { dg-error "use of deleted function" "" { 
xfail *-*-* } }
+  B* b2 = new B(eb);           // { dg-error "use of deleted function" }
+}

Reply via email to