1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 2 3 struct Trivial {}; 4 struct NonTrivial { 5 NonTrivial(NonTrivial&&); 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; 13 DeletedNTVariant(DeletedNTVariant&&); 14 }; 15 DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}} 16 17 struct DeletedNTVariant2 { 18 union { 19 NonTrivial NT; 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; 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; 55 IsAmbiguous(IsAmbiguous&&); 56 }; 57 IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}} 58 59 struct Deleted { 60 IsAmbiguous IA; 61 Deleted(Deleted&&); 62 }; 63 Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} 64 65 // It's implied (but not stated) that this should also happen if overload 66 // resolution fails. 67 struct ConstMember { 68 const Trivial ct; 69 ConstMember(ConstMember&&); 70 }; 71 ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor 72 struct ConstMoveOnlyMember { 73 const NonTrivial cnt; 74 ConstMoveOnlyMember(ConstMoveOnlyMember&&); 75 }; 76 ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}} 77 struct VolatileMember { 78 volatile Trivial vt; 79 VolatileMember(VolatileMember&&); 80 }; 81 VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}} 82 83 // -- a direct or virtual base class B that cannot be moved because overload 84 // resolution results in an ambiguity or a function that is deleted or 85 // inaccessible 86 struct AmbiguousMoveBase : Ambiguity { 87 AmbiguousMoveBase(AmbiguousMoveBase&&); 88 }; 89 AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}} 90 91 struct DeletedMoveBase : AmbiguousMoveBase { 92 DeletedMoveBase(DeletedMoveBase&&); 93 }; 94 DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}} 95 96 struct InaccessibleMoveBase : NoAccess { 97 InaccessibleMoveBase(InaccessibleMoveBase&&); 98 }; 99 InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}} 100 101 // -- any direct or virtual base class or non-static data member of a type with 102 // a destructor that is deleted or inaccessible 103 struct NoAccessDtor { 104 NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}} 105 private: 106 ~NoAccessDtor(); 107 friend struct HasAccessDtor; 108 }; 109 110 struct HasNoAccessDtor { 111 NoAccessDtor NAD; 112 HasNoAccessDtor(HasNoAccessDtor&&); 113 }; 114 HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}} 115 116 struct HasAccessDtor { 117 NoAccessDtor NAD; 118 HasAccessDtor(HasAccessDtor&&); 119 }; 120 HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default; 121 122 struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}} 123 }; 124 extern HasNoAccessDtorBase HNADBa; 125 HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}} 126 127 // The restriction on rvalue reference members applies to only the copy 128 // constructor. 129 struct RValue { 130 int &&ri = 1; // expected-warning {{binding reference member 'ri' to a temporary}} expected-note {{here}} 131 RValue(RValue&&); 132 }; 133 RValue::RValue(RValue&&) = default; 134 135 // -- a non-static data member or direct or virtual base class with a type that 136 // does not have a move constructor and is not trivially copyable 137 struct CopyOnly { 138 CopyOnly(const CopyOnly&); 139 }; 140 141 struct NonMove { 142 CopyOnly CO; 143 NonMove(NonMove&&); 144 }; 145 NonMove::NonMove(NonMove&&) = default; // ok under DR1402 146 147 struct Moveable { 148 Moveable(); 149 Moveable(Moveable&&); 150 }; 151 152 struct HasMove { 153 Moveable M; 154 HasMove(HasMove&&); 155 }; 156 HasMove::HasMove(HasMove&&) = default; 157 158 namespace DR1402 { 159 struct member { 160 member(); 161 member(const member&); 162 member& operator=(const member&); 163 ~member(); 164 }; 165 166 struct A { 167 member m_; 168 169 A() = default; 170 A(const A&) = default; 171 A& operator=(const A&) = default; 172 A(A&&) = default; 173 A& operator=(A&&) = default; 174 ~A() = default; 175 }; 176 177 // ok, A's explicitly-defaulted move operations copy m_. 178 void f() { 179 A a, b(a), c(static_cast<A&&>(a)); 180 a = b; 181 b = static_cast<A&&>(c); 182 } 183 } 184