19ca5c425SRichard Smith // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 277c1f9f8SAlexis Hunt 3c91d12ceSRichard Smith struct Trivial {}; 477c1f9f8SAlexis Hunt struct NonTrivial { 5566184acSRichard Smith NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}} 677c1f9f8SAlexis Hunt }; 7dd5619feSRichard Smith struct DeletedCopy { 8dd5619feSRichard Smith DeletedCopy(const DeletedCopy&) = delete; 9dd5619feSRichard Smith }; 1077c1f9f8SAlexis Hunt 11522fa537SRichard Smith // A defaulted move constructor for a class X is defined as deleted if X has: 12522fa537SRichard Smith 13522fa537SRichard Smith // -- a variant member with a non-trivial corresponding constructor 1477c1f9f8SAlexis Hunt union DeletedNTVariant { 15566184acSRichard Smith NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}} 1677c1f9f8SAlexis Hunt DeletedNTVariant(DeletedNTVariant&&); 1777c1f9f8SAlexis Hunt }; 1877c1f9f8SAlexis Hunt DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}} 1977c1f9f8SAlexis Hunt 2077c1f9f8SAlexis Hunt struct DeletedNTVariant2 { 2177c1f9f8SAlexis Hunt union { 22566184acSRichard Smith NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}} 2377c1f9f8SAlexis Hunt }; 2477c1f9f8SAlexis Hunt DeletedNTVariant2(DeletedNTVariant2&&); 2577c1f9f8SAlexis Hunt }; 2677c1f9f8SAlexis Hunt DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}} 2777c1f9f8SAlexis Hunt 28dd5619feSRichard Smith // Note, move constructor is not a candidate because it is deleted. 29dd5619feSRichard Smith template<typename T> struct DeletedNTVariant3 { // expected-note 2{{default}} expected-note 2{{copy}} 30dd5619feSRichard Smith union { 31dd5619feSRichard Smith T NT; 32dd5619feSRichard Smith }; 33dd5619feSRichard Smith }; 34dd5619feSRichard Smith extern DeletedNTVariant3<NonTrivial> dntv3a(0); // expected-error {{no matching}} 35*89d9912cSHaojian Wu extern DeletedNTVariant3<DeletedCopy> dntv3b(0); // expected-error {{no matching}} 36dd5619feSRichard Smith 37522fa537SRichard Smith // -- a non-static data member of class type M (or array thereof) that cannot be 38522fa537SRichard Smith // copied because overload resolution results in an ambiguity or a function 39522fa537SRichard Smith // that is deleted or inaccessible 4077c1f9f8SAlexis Hunt struct NoAccess { 4177c1f9f8SAlexis Hunt NoAccess() = default; 4277c1f9f8SAlexis Hunt private: 4377c1f9f8SAlexis Hunt NoAccess(NoAccess&&); 4477c1f9f8SAlexis Hunt 4577c1f9f8SAlexis Hunt friend struct HasAccess; 4677c1f9f8SAlexis Hunt }; 4777c1f9f8SAlexis Hunt 4877c1f9f8SAlexis Hunt struct HasNoAccess { 49566184acSRichard Smith NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}} 5077c1f9f8SAlexis Hunt HasNoAccess(HasNoAccess&&); 5177c1f9f8SAlexis Hunt }; 5277c1f9f8SAlexis Hunt HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}} 5377c1f9f8SAlexis Hunt 5477c1f9f8SAlexis Hunt struct HasAccess { 5577c1f9f8SAlexis Hunt NoAccess NA; 5677c1f9f8SAlexis Hunt HasAccess(HasAccess&&); 5777c1f9f8SAlexis Hunt }; 5877c1f9f8SAlexis Hunt HasAccess::HasAccess(HasAccess&&) = default; 5977c1f9f8SAlexis Hunt 60522fa537SRichard Smith struct Ambiguity { 61522fa537SRichard Smith Ambiguity(const Ambiguity&&); 62522fa537SRichard Smith Ambiguity(volatile Ambiguity&&); 63522fa537SRichard Smith }; 64522fa537SRichard Smith 65522fa537SRichard Smith struct IsAmbiguous { 66566184acSRichard Smith Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}} 67566184acSRichard Smith IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}} 68522fa537SRichard Smith }; 69522fa537SRichard Smith IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}} 70522fa537SRichard Smith 71522fa537SRichard Smith struct Deleted { 72566184acSRichard Smith // FIXME: This diagnostic is slightly wrong: the constructor we select to move 73566184acSRichard Smith // 'IA' is deleted, but we select the copy constructor (we ignore the move 74566184acSRichard Smith // constructor, because it was defaulted and deleted). 75566184acSRichard Smith IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}} 76522fa537SRichard Smith Deleted(Deleted&&); 77522fa537SRichard Smith }; 78522fa537SRichard Smith Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} 79522fa537SRichard Smith 80c91d12ceSRichard Smith // It's implied (but not stated) that this should also happen if overload 81c91d12ceSRichard Smith // resolution fails. 82c91d12ceSRichard Smith struct ConstMember { 83c91d12ceSRichard Smith const Trivial ct; 84c91d12ceSRichard Smith ConstMember(ConstMember&&); 85c91d12ceSRichard Smith }; 86c91d12ceSRichard Smith ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor 87c91d12ceSRichard Smith struct ConstMoveOnlyMember { 88566184acSRichard Smith // FIXME: This diagnostic is slightly wrong: the constructor we select to move 89566184acSRichard Smith // 'cnt' is deleted, but we select the copy constructor, because the object is 90566184acSRichard Smith // const. 91566184acSRichard Smith const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}} 92c91d12ceSRichard Smith ConstMoveOnlyMember(ConstMoveOnlyMember&&); 93c91d12ceSRichard Smith }; 94c91d12ceSRichard Smith ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}} 95c91d12ceSRichard Smith struct VolatileMember { 96566184acSRichard Smith volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}} 97c91d12ceSRichard Smith VolatileMember(VolatileMember&&); 98c91d12ceSRichard Smith }; 99c91d12ceSRichard Smith VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}} 100c91d12ceSRichard Smith 101522fa537SRichard Smith // -- a direct or virtual base class B that cannot be moved because overload 102522fa537SRichard Smith // resolution results in an ambiguity or a function that is deleted or 103522fa537SRichard Smith // inaccessible 104566184acSRichard Smith struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}} 105566184acSRichard Smith AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}} 106522fa537SRichard Smith }; 107522fa537SRichard Smith AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}} 108522fa537SRichard Smith 109566184acSRichard Smith struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}} 110522fa537SRichard Smith DeletedMoveBase(DeletedMoveBase&&); 111522fa537SRichard Smith }; 112522fa537SRichard Smith DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}} 113522fa537SRichard Smith 114566184acSRichard Smith struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}} 115522fa537SRichard Smith InaccessibleMoveBase(InaccessibleMoveBase&&); 116522fa537SRichard Smith }; 117522fa537SRichard Smith InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}} 118522fa537SRichard Smith 119522fa537SRichard Smith // -- any direct or virtual base class or non-static data member of a type with 120522fa537SRichard Smith // a destructor that is deleted or inaccessible 12177c1f9f8SAlexis Hunt struct NoAccessDtor { 122852265ffSRichard Smith NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}} 12377c1f9f8SAlexis Hunt private: 12477c1f9f8SAlexis Hunt ~NoAccessDtor(); 12577c1f9f8SAlexis Hunt friend struct HasAccessDtor; 12677c1f9f8SAlexis Hunt }; 12777c1f9f8SAlexis Hunt 12877c1f9f8SAlexis Hunt struct HasNoAccessDtor { 129566184acSRichard Smith NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}} 13077c1f9f8SAlexis Hunt HasNoAccessDtor(HasNoAccessDtor&&); 13177c1f9f8SAlexis Hunt }; 13277c1f9f8SAlexis Hunt HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}} 13377c1f9f8SAlexis Hunt 13477c1f9f8SAlexis Hunt struct HasAccessDtor { 13577c1f9f8SAlexis Hunt NoAccessDtor NAD; 13677c1f9f8SAlexis Hunt HasAccessDtor(HasAccessDtor&&); 13777c1f9f8SAlexis Hunt }; 13877c1f9f8SAlexis Hunt HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default; 13977c1f9f8SAlexis Hunt 140852265ffSRichard Smith struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}} 141522fa537SRichard Smith }; 142522fa537SRichard Smith extern HasNoAccessDtorBase HNADBa; 143522fa537SRichard Smith HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}} 144522fa537SRichard Smith 145522fa537SRichard Smith // The restriction on rvalue reference members applies to only the copy 146522fa537SRichard Smith // constructor. 14777c1f9f8SAlexis Hunt struct RValue { 148d87aab93SRichard Smith int &&ri = 1; 14977c1f9f8SAlexis Hunt RValue(RValue&&); 15077c1f9f8SAlexis Hunt }; 15177c1f9f8SAlexis Hunt RValue::RValue(RValue&&) = default; 15277c1f9f8SAlexis Hunt 153522fa537SRichard Smith // -- a non-static data member or direct or virtual base class with a type that 154522fa537SRichard Smith // does not have a move constructor and is not trivially copyable 15577c1f9f8SAlexis Hunt struct CopyOnly { 15677c1f9f8SAlexis Hunt CopyOnly(const CopyOnly&); 15777c1f9f8SAlexis Hunt }; 15877c1f9f8SAlexis Hunt 15977c1f9f8SAlexis Hunt struct NonMove { 16077c1f9f8SAlexis Hunt CopyOnly CO; 16177c1f9f8SAlexis Hunt NonMove(NonMove&&); 16277c1f9f8SAlexis Hunt }; 163cf8ec8daSRichard Smith NonMove::NonMove(NonMove&&) = default; // ok under DR1402 16477c1f9f8SAlexis Hunt 16577c1f9f8SAlexis Hunt struct Moveable { 16677c1f9f8SAlexis Hunt Moveable(); 16777c1f9f8SAlexis Hunt Moveable(Moveable&&); 16877c1f9f8SAlexis Hunt }; 16977c1f9f8SAlexis Hunt 17077c1f9f8SAlexis Hunt struct HasMove { 17177c1f9f8SAlexis Hunt Moveable M; 17277c1f9f8SAlexis Hunt HasMove(HasMove&&); 17377c1f9f8SAlexis Hunt }; 17477c1f9f8SAlexis Hunt HasMove::HasMove(HasMove&&) = default; 175cf8ec8daSRichard Smith 176cf8ec8daSRichard Smith namespace DR1402 { 177cf8ec8daSRichard Smith struct member { 178cf8ec8daSRichard Smith member(); 179cf8ec8daSRichard Smith member(const member&); 180cf8ec8daSRichard Smith member& operator=(const member&); 181cf8ec8daSRichard Smith ~member(); 182cf8ec8daSRichard Smith }; 183cf8ec8daSRichard Smith 184cf8ec8daSRichard Smith struct A { 185cf8ec8daSRichard Smith member m_; 186cf8ec8daSRichard Smith 187cf8ec8daSRichard Smith A() = default; 188cf8ec8daSRichard Smith A(const A&) = default; 189cf8ec8daSRichard Smith A& operator=(const A&) = default; 190cf8ec8daSRichard Smith A(A&&) = default; 191cf8ec8daSRichard Smith A& operator=(A&&) = default; 192cf8ec8daSRichard Smith ~A() = default; 193cf8ec8daSRichard Smith }; 194cf8ec8daSRichard Smith 195cf8ec8daSRichard Smith // ok, A's explicitly-defaulted move operations copy m_. f()196cf8ec8daSRichard Smith void f() { 197cf8ec8daSRichard Smith A a, b(a), c(static_cast<A&&>(a)); 198cf8ec8daSRichard Smith a = b; 199cf8ec8daSRichard Smith b = static_cast<A&&>(c); 200cf8ec8daSRichard Smith } 201cf8ec8daSRichard Smith } 202