diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-22 20:09:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-22 20:09:10 +0000 |
commit | 566184ac7591e693cc5375cfccd9ccac4ae6eddb (patch) | |
tree | 72f94bc20f190dd9c36dc422b269f9959b80eebd /clang | |
parent | 80429048db141e0bc5da60c568e43cb381d94dfd (diff) | |
download | bcm5719-llvm-566184ac7591e693cc5375cfccd9ccac4ae6eddb.tar.gz bcm5719-llvm-566184ac7591e693cc5375cfccd9ccac4ae6eddb.zip |
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.
llvm-svn: 199829
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 1 | ||||
-rw-r--r-- | clang/test/CXX/special/class.copy/p11.0x.copy.cpp | 4 | ||||
-rw-r--r-- | clang/test/CXX/special/class.copy/p11.0x.move.cpp | 34 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp | 4 |
4 files changed, 25 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 3fe6337d502..019b1c189c2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4917,6 +4917,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { // [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; } } diff --git a/clang/test/CXX/special/class.copy/p11.0x.copy.cpp b/clang/test/CXX/special/class.copy/p11.0x.copy.cpp index 19e7683608f..1ca0143d093 100644 --- a/clang/test/CXX/special/class.copy/p11.0x.copy.cpp +++ b/clang/test/CXX/special/class.copy/p11.0x.copy.cpp @@ -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}} diff --git a/clang/test/CXX/special/class.copy/p11.0x.move.cpp b/clang/test/CXX/special/class.copy/p11.0x.move.cpp index 1dce27a8329..514817d2b71 100644 --- a/clang/test/CXX/special/class.copy/p11.0x.move.cpp +++ b/clang/test/CXX/special/class.copy/p11.0x.move.cpp @@ -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(VolatileMember&&) = default; // expected-error{{w // -- 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}} diff --git a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp index 0cebc10ade4..b9af67948bf 100644 --- a/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp +++ b/clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp @@ -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}} |