diff mbox

C++0x PATCH to implement core 1191 (deleted base destructor)

Message ID 4D7FADE8.1040400@redhat.com
State New
Headers show

Commit Message

Jason Merrill March 15, 2011, 6:20 p.m. UTC
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 <jason@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 mbox

Patch

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" }
+}