forked from OSchip/llvm-project
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
This commit is contained in:
parent
80429048db
commit
566184ac75
|
@ -4917,6 +4917,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
|
||||||
// [For a] user-provided explicitly-defaulted function [...] if such a
|
// [For a] user-provided explicitly-defaulted function [...] if such a
|
||||||
// function is implicitly defined as deleted, the program is ill-formed.
|
// function is implicitly defined as deleted, the program is ill-formed.
|
||||||
Diag(MD->getLocation(), diag::err_out_of_line_default_deletes) << CSM;
|
Diag(MD->getLocation(), diag::err_out_of_line_default_deletes) << CSM;
|
||||||
|
ShouldDeleteSpecialMember(MD, CSM, /*Diagnose*/true);
|
||||||
HadError = true;
|
HadError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ namespace PR13381 {
|
||||||
namespace Mutable {
|
namespace Mutable {
|
||||||
struct A {
|
struct A {
|
||||||
A(const A &);
|
A(const A &);
|
||||||
A(A &) = delete;
|
A(A &) = delete; // expected-note {{deleted here}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
|
@ -153,7 +153,7 @@ namespace Mutable {
|
||||||
B::B(const B &) = default;
|
B::B(const B &) = default;
|
||||||
|
|
||||||
struct C {
|
struct C {
|
||||||
mutable A a;
|
mutable A a; // expected-note {{deleted because field 'a' has a deleted copy constructor}}
|
||||||
C(const C &);
|
C(const C &);
|
||||||
};
|
};
|
||||||
C::C(const C &) = default; // expected-error{{would delete}}
|
C::C(const C &) = default; // expected-error{{would delete}}
|
||||||
|
|
|
@ -2,21 +2,21 @@
|
||||||
|
|
||||||
struct Trivial {};
|
struct Trivial {};
|
||||||
struct NonTrivial {
|
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 defaulted move constructor for a class X is defined as deleted if X has:
|
||||||
|
|
||||||
// -- a variant member with a non-trivial corresponding constructor
|
// -- a variant member with a non-trivial corresponding constructor
|
||||||
union DeletedNTVariant {
|
union DeletedNTVariant {
|
||||||
NonTrivial NT;
|
NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
|
||||||
DeletedNTVariant(DeletedNTVariant&&);
|
DeletedNTVariant(DeletedNTVariant&&);
|
||||||
};
|
};
|
||||||
DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
|
DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
|
||||||
|
|
||||||
struct DeletedNTVariant2 {
|
struct DeletedNTVariant2 {
|
||||||
union {
|
union {
|
||||||
NonTrivial NT;
|
NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
|
||||||
};
|
};
|
||||||
DeletedNTVariant2(DeletedNTVariant2&&);
|
DeletedNTVariant2(DeletedNTVariant2&&);
|
||||||
};
|
};
|
||||||
|
@ -34,7 +34,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HasNoAccess {
|
struct HasNoAccess {
|
||||||
NoAccess NA;
|
NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
|
||||||
HasNoAccess(HasNoAccess&&);
|
HasNoAccess(HasNoAccess&&);
|
||||||
};
|
};
|
||||||
HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
|
HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
|
||||||
|
@ -51,13 +51,16 @@ struct Ambiguity {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IsAmbiguous {
|
struct IsAmbiguous {
|
||||||
Ambiguity A;
|
Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}
|
||||||
IsAmbiguous(IsAmbiguous&&);
|
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}}
|
IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
|
||||||
|
|
||||||
struct Deleted {
|
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::Deleted(Deleted&&) = default; // expected-error{{would delete}}
|
Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}
|
||||||
|
@ -70,12 +73,15 @@ struct ConstMember {
|
||||||
};
|
};
|
||||||
ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
|
ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
|
||||||
struct ConstMoveOnlyMember {
|
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::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
|
ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
|
||||||
struct VolatileMember {
|
struct VolatileMember {
|
||||||
volatile Trivial vt;
|
volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
|
||||||
VolatileMember(VolatileMember&&);
|
VolatileMember(VolatileMember&&);
|
||||||
};
|
};
|
||||||
VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}
|
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
|
// -- 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
|
// resolution results in an ambiguity or a function that is deleted or
|
||||||
// inaccessible
|
// inaccessible
|
||||||
struct AmbiguousMoveBase : Ambiguity {
|
struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
|
||||||
AmbiguousMoveBase(AmbiguousMoveBase&&);
|
AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
|
||||||
};
|
};
|
||||||
AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
|
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::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
|
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::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
|
InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
|
||||||
|
@ -108,7 +114,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HasNoAccessDtor {
|
struct HasNoAccessDtor {
|
||||||
NoAccessDtor NAD;
|
NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
|
||||||
HasNoAccessDtor(HasNoAccessDtor&&);
|
HasNoAccessDtor(HasNoAccessDtor&&);
|
||||||
};
|
};
|
||||||
HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
|
HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct good_const {
|
||||||
good_const gc;
|
good_const gc;
|
||||||
|
|
||||||
struct no_default {
|
struct no_default {
|
||||||
no_default() = delete; // expected-note 3{{deleted here}}
|
no_default() = delete; // expected-note 4{{deleted here}}
|
||||||
};
|
};
|
||||||
struct no_dtor {
|
struct no_dtor {
|
||||||
~no_dtor() = delete; // expected-note 2{{deleted here}}
|
~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}}
|
defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
|
||||||
|
|
||||||
struct late_delete {
|
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::late_delete() = default; // expected-error {{would delete it}}
|
late_delete::late_delete() = default; // expected-error {{would delete it}}
|
||||||
|
|
Loading…
Reference in New Issue