202 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s2 3struct Trivial {};4struct NonTrivial {5 NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}}6};7struct DeletedCopy {8 DeletedCopy(const DeletedCopy&) = delete;9};10 11// A defaulted move constructor for a class X is defined as deleted if X has:12 13// -- a variant member with a non-trivial corresponding constructor14union DeletedNTVariant {15 NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}16 DeletedNTVariant(DeletedNTVariant&&);17};18DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}19 20struct DeletedNTVariant2 {21 union {22 NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}23 };24 DeletedNTVariant2(DeletedNTVariant2&&);25};26DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}}27 28// Note, move constructor is not a candidate because it is deleted.29template<typename T> struct DeletedNTVariant3 { // expected-note 2{{default}} expected-note 2{{copy}}30 union {31 T NT;32 };33};34extern DeletedNTVariant3<NonTrivial> dntv3a(0); // expected-error {{no matching}}35extern DeletedNTVariant3<DeletedCopy> dntv3b(0); // expected-error {{no matching}}36 37// -- a non-static data member of class type M (or array thereof) that cannot be38// copied because overload resolution results in an ambiguity or a function39// that is deleted or inaccessible40struct NoAccess {41 NoAccess() = default;42private:43 NoAccess(NoAccess&&);44 45 friend struct HasAccess;46};47 48struct HasNoAccess {49 NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}50 HasNoAccess(HasNoAccess&&);51};52HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}53 54struct HasAccess {55 NoAccess NA;56 HasAccess(HasAccess&&);57};58HasAccess::HasAccess(HasAccess&&) = default;59 60struct Ambiguity {61 Ambiguity(const Ambiguity&&);62 Ambiguity(volatile Ambiguity&&);63};64 65struct IsAmbiguous {66 Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}67 IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}}68};69IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}70 71struct Deleted {72 // FIXME: This diagnostic is slightly wrong: the constructor we select to move73 // 'IA' is deleted, but we select the copy constructor (we ignore the move74 // constructor, because it was defaulted and deleted).75 IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}}76 Deleted(Deleted&&);77};78Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}79 80// It's implied (but not stated) that this should also happen if overload81// resolution fails.82struct ConstMember {83 const Trivial ct;84 ConstMember(ConstMember&&);85};86ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor87struct ConstMoveOnlyMember {88 // FIXME: This diagnostic is slightly wrong: the constructor we select to move89 // 'cnt' is deleted, but we select the copy constructor, because the object is90 // const.91 const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}}92 ConstMoveOnlyMember(ConstMoveOnlyMember&&);93};94ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}95struct VolatileMember {96 volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}97 VolatileMember(VolatileMember&&);98};99VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}100 101// -- a direct or virtual base class B that cannot be moved because overload102// resolution results in an ambiguity or a function that is deleted or103// inaccessible104struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}105 AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}106};107AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}108 109struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}110 DeletedMoveBase(DeletedMoveBase&&);111};112DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}113 114struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}115 InaccessibleMoveBase(InaccessibleMoveBase&&);116};117InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}118 119// -- any direct or virtual base class or non-static data member of a type with120// a destructor that is deleted or inaccessible121struct NoAccessDtor {122 NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}123private:124 ~NoAccessDtor();125 friend struct HasAccessDtor;126};127 128struct HasNoAccessDtor {129 NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}130 HasNoAccessDtor(HasNoAccessDtor&&);131};132HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}133 134struct HasAccessDtor {135 NoAccessDtor NAD;136 HasAccessDtor(HasAccessDtor&&);137};138HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;139 140struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}141};142extern HasNoAccessDtorBase HNADBa;143HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}144 145// The restriction on rvalue reference members applies to only the copy146// constructor.147struct RValue {148 int &&ri = 1;149 RValue(RValue&&);150};151RValue::RValue(RValue&&) = default;152 153// -- a non-static data member or direct or virtual base class with a type that154// does not have a move constructor and is not trivially copyable155struct CopyOnly {156 CopyOnly(const CopyOnly&);157};158 159struct NonMove {160 CopyOnly CO;161 NonMove(NonMove&&);162};163NonMove::NonMove(NonMove&&) = default; // ok under DR1402164 165struct Moveable {166 Moveable();167 Moveable(Moveable&&);168};169 170struct HasMove {171 Moveable M;172 HasMove(HasMove&&);173};174HasMove::HasMove(HasMove&&) = default;175 176namespace DR1402 {177 struct member {178 member();179 member(const member&);180 member& operator=(const member&);181 ~member();182 };183 184 struct A {185 member m_;186 187 A() = default;188 A(const A&) = default;189 A& operator=(const A&) = default;190 A(A&&) = default;191 A& operator=(A&&) = default;192 ~A() = default;193 };194 195 // ok, A's explicitly-defaulted move operations copy m_.196 void f() {197 A a, b(a), c(static_cast<A&&>(a));198 a = b;199 b = static_cast<A&&>(c);200 }201}202