r199829 - When a special member is explicitly defaulted outside its class, and we reject

Richard Smith richard-llvm at metafoo.co.uk
Wed Jan 22 12:09:10 PST 2014


Author: rsmith
Date: Wed Jan 22 14:09:10 2014
New Revision: 199829

URL: http://llvm.org/viewvc/llvm-project?rev=199829&view=rev
Log:
When a special member is explicitly defaulted outside its class, and we reject
the defaulting because it would delete the member, produce additional notes
explaining why the member is implicitly deleted.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/special/class.copy/p11.0x.copy.cpp
    cfe/trunk/test/CXX/special/class.copy/p11.0x.move.cpp
    cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=199829&r1=199828&r2=199829&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jan 22 14:09:10 2014
@@ -4917,6 +4917,7 @@ void Sema::CheckExplicitlyDefaultedSpeci
       //   [For a] user-provided explicitly-defaulted function [...] if such a
       //   function is implicitly defined as deleted, the program is ill-formed.
       Diag(MD->getLocation(), diag::err_out_of_line_default_deletes) << CSM;
+      ShouldDeleteSpecialMember(MD, CSM, /*Diagnose*/true);
       HadError = true;
     }
   }

Modified: cfe/trunk/test/CXX/special/class.copy/p11.0x.copy.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p11.0x.copy.cpp?rev=199829&r1=199828&r2=199829&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.copy/p11.0x.copy.cpp (original)
+++ cfe/trunk/test/CXX/special/class.copy/p11.0x.copy.cpp Wed Jan 22 14:09:10 2014
@@ -143,7 +143,7 @@ namespace PR13381 {
 namespace Mutable {
   struct A {
     A(const A &);
-    A(A &) = delete;
+    A(A &) = delete; // expected-note {{deleted here}}
   };
 
   struct B {
@@ -153,7 +153,7 @@ namespace Mutable {
   B::B(const B &) = default;
 
   struct C {
-    mutable A a;
+    mutable A a; // expected-note {{deleted because field 'a' has a deleted copy constructor}}
     C(const C &);
   };
   C::C(const C &) = default; // expected-error{{would delete}}

Modified: cfe/trunk/test/CXX/special/class.copy/p11.0x.move.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p11.0x.move.cpp?rev=199829&r1=199828&r2=199829&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.copy/p11.0x.move.cpp (original)
+++ cfe/trunk/test/CXX/special/class.copy/p11.0x.move.cpp Wed Jan 22 14:09:10 2014
@@ -2,21 +2,21 @@
 
 struct Trivial {};
 struct NonTrivial {
-  NonTrivial(NonTrivial&&);
+  NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}}
 };
 
 // A defaulted move constructor for a class X is defined as deleted if X has:
 
 // -- a variant member with a non-trivial corresponding constructor
 union DeletedNTVariant {
-  NonTrivial NT;
+  NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
   DeletedNTVariant(DeletedNTVariant&&);
 };
 DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
 
 struct DeletedNTVariant2 {
   union {
-    NonTrivial NT;
+    NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
   };
   DeletedNTVariant2(DeletedNTVariant2&&);
 };
@@ -34,7 +34,7 @@ private:
 };
 
 struct HasNoAccess {
-  NoAccess NA;
+  NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
   HasNoAccess(HasNoAccess&&);
 };
 HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
@@ -51,13 +51,16 @@ struct Ambiguity {
 };
 
 struct IsAmbiguous {
-  Ambiguity A;
-  IsAmbiguous(IsAmbiguous&&);
+  Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}
+  IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}}
 };
 IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
 
 struct Deleted {
-  IsAmbiguous IA;
+  // FIXME: This diagnostic is slightly wrong: the constructor we select to move
+  // 'IA' is deleted, but we select the copy constructor (we ignore the move
+  // constructor, because it was defaulted and deleted).
+  IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}}
   Deleted(Deleted&&);
 };
 Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}
@@ -70,12 +73,15 @@ struct ConstMember {
 };
 ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
 struct ConstMoveOnlyMember {
-  const NonTrivial cnt;
+  // FIXME: This diagnostic is slightly wrong: the constructor we select to move
+  // 'cnt' is deleted, but we select the copy constructor, because the object is
+  // const.
+  const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}}
   ConstMoveOnlyMember(ConstMoveOnlyMember&&);
 };
 ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
 struct VolatileMember {
-  volatile Trivial vt;
+  volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
   VolatileMember(VolatileMember&&);
 };
 VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}
@@ -83,17 +89,17 @@ VolatileMember::VolatileMember(VolatileM
 // -- a direct or virtual base class B that cannot be moved because overload
 //    resolution results in an ambiguity or a function that is deleted or
 //    inaccessible
-struct AmbiguousMoveBase : Ambiguity {
-  AmbiguousMoveBase(AmbiguousMoveBase&&);
+struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
+  AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
 };
 AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
 
-struct DeletedMoveBase : AmbiguousMoveBase {
+struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
   DeletedMoveBase(DeletedMoveBase&&);
 };
 DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
 
-struct InaccessibleMoveBase : NoAccess {
+struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
   InaccessibleMoveBase(InaccessibleMoveBase&&);
 };
 InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
@@ -108,7 +114,7 @@ private:
 };
 
 struct HasNoAccessDtor {
-  NoAccessDtor NAD;
+  NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
   HasNoAccessDtor(HasNoAccessDtor&&);
 };
 HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}

Modified: cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp?rev=199829&r1=199828&r2=199829&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp Wed Jan 22 14:09:10 2014
@@ -59,7 +59,7 @@ struct good_const {
 good_const gc;
 
 struct no_default {
-  no_default() = delete; // expected-note 3{{deleted here}}
+  no_default() = delete; // expected-note 4{{deleted here}}
 };
 struct no_dtor {
   ~no_dtor() = delete; // expected-note 2{{deleted here}}
@@ -114,7 +114,7 @@ struct defaulted_delete {
 defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct late_delete {
-  no_default nd;
+  no_default nd; // expected-note {{because field 'nd' has a deleted default constructor}}
   late_delete();
 };
 late_delete::late_delete() = default; // expected-error {{would delete it}}





More information about the cfe-commits mailing list