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