1*67e74705SXin Li // RUN: %clang_cc1 -verify %s -std=c++11 2*67e74705SXin Li 3*67e74705SXin Li struct Trivial {}; 4*67e74705SXin Li 5*67e74705SXin Li template<typename T> struct CopyAssign { 6*67e74705SXin Li static T t; testCopyAssign7*67e74705SXin Li void test() { 8*67e74705SXin Li t = t; // expected-error +{{deleted}} 9*67e74705SXin Li } 10*67e74705SXin Li }; 11*67e74705SXin Li template<typename T> struct MoveAssign { 12*67e74705SXin Li static T t; testMoveAssign13*67e74705SXin Li void test() { 14*67e74705SXin Li // Overload resolution will ignore a defaulted, deleted move assignment, 15*67e74705SXin Li // so check for it in a different way. 16*67e74705SXin Li T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}} 17*67e74705SXin Li } 18*67e74705SXin Li }; 19*67e74705SXin Li template<typename T> struct MoveOrCopyAssign { 20*67e74705SXin Li static T t; testMoveOrCopyAssign21*67e74705SXin Li void test() { 22*67e74705SXin Li t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}} 23*67e74705SXin Li } 24*67e74705SXin Li }; 25*67e74705SXin Li 26*67e74705SXin Li struct NonTrivialCopyAssign { 27*67e74705SXin Li NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &); 28*67e74705SXin Li }; 29*67e74705SXin Li struct NonTrivialMoveAssign { 30*67e74705SXin Li NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&); 31*67e74705SXin Li }; 32*67e74705SXin Li struct AmbiguousCopyAssign { 33*67e74705SXin Li AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile; 34*67e74705SXin Li AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const; 35*67e74705SXin Li }; 36*67e74705SXin Li struct AmbiguousMoveAssign { 37*67e74705SXin Li AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&); 38*67e74705SXin Li AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&); 39*67e74705SXin Li }; 40*67e74705SXin Li struct DeletedCopyAssign { 41*67e74705SXin Li DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}} 42*67e74705SXin Li }; 43*67e74705SXin Li struct DeletedMoveAssign { 44*67e74705SXin Li DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}} 45*67e74705SXin Li }; 46*67e74705SXin Li class InaccessibleCopyAssign { 47*67e74705SXin Li InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &); 48*67e74705SXin Li }; 49*67e74705SXin Li class InaccessibleMoveAssign { 50*67e74705SXin Li InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&); 51*67e74705SXin Li }; 52*67e74705SXin Li class NonConstCopyAssign { 53*67e74705SXin Li NonConstCopyAssign &operator=(NonConstCopyAssign &); 54*67e74705SXin Li }; 55*67e74705SXin Li 56*67e74705SXin Li // A defaulted copy/move assignment operator for class X is defined as deleted 57*67e74705SXin Li // if X has: 58*67e74705SXin Li 59*67e74705SXin Li // -- a variant member with a non-trivial corresponding assignment operator 60*67e74705SXin Li // and X is a union-like class 61*67e74705SXin Li struct A1 { 62*67e74705SXin Li union { 63*67e74705SXin Li NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}} 64*67e74705SXin Li }; 65*67e74705SXin Li }; 66*67e74705SXin Li template struct CopyAssign<A1>; // expected-note {{here}} 67*67e74705SXin Li 68*67e74705SXin Li struct A2 { 69*67e74705SXin Li A2 &operator=(A2 &&) = default; // expected-note {{here}} 70*67e74705SXin Li union { 71*67e74705SXin Li NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}} 72*67e74705SXin Li }; 73*67e74705SXin Li }; 74*67e74705SXin Li template struct MoveAssign<A2>; // expected-note {{here}} 75*67e74705SXin Li 76*67e74705SXin Li // -- a non-static const data member of (array of) non-class type 77*67e74705SXin Li struct B1 { 78*67e74705SXin Li const int a; // expected-note 2{{field 'a' is of const-qualified type}} 79*67e74705SXin Li }; 80*67e74705SXin Li struct B2 { 81*67e74705SXin Li const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}} 82*67e74705SXin Li }; 83*67e74705SXin Li struct B3 { 84*67e74705SXin Li const void *a[3]; 85*67e74705SXin Li }; 86*67e74705SXin Li template struct CopyAssign<B1>; // expected-note {{here}} 87*67e74705SXin Li template struct MoveAssign<B1>; // expected-note {{here}} 88*67e74705SXin Li template struct CopyAssign<B2>; // expected-note {{here}} 89*67e74705SXin Li template struct MoveAssign<B2>; // expected-note {{here}} 90*67e74705SXin Li template struct CopyAssign<B3>; 91*67e74705SXin Li template struct MoveAssign<B3>; 92*67e74705SXin Li 93*67e74705SXin Li // -- a non-static data member of reference type 94*67e74705SXin Li struct C1 { 95*67e74705SXin Li int &a; // expected-note 2{{field 'a' is of reference type 'int &'}} 96*67e74705SXin Li }; 97*67e74705SXin Li template struct CopyAssign<C1>; // expected-note {{here}} 98*67e74705SXin Li template struct MoveAssign<C1>; // expected-note {{here}} 99*67e74705SXin Li 100*67e74705SXin Li // -- a non-static data member of class type M that cannot be copied/moved 101*67e74705SXin Li struct D1 { 102*67e74705SXin Li AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}} 103*67e74705SXin Li }; 104*67e74705SXin Li struct D2 { 105*67e74705SXin Li D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} 106*67e74705SXin Li AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}} 107*67e74705SXin Li }; 108*67e74705SXin Li struct D3 { 109*67e74705SXin Li DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}} 110*67e74705SXin Li }; 111*67e74705SXin Li struct D4 { 112*67e74705SXin Li D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} 113*67e74705SXin Li DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}} 114*67e74705SXin Li }; 115*67e74705SXin Li struct D5 { 116*67e74705SXin Li InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}} 117*67e74705SXin Li }; 118*67e74705SXin Li struct D6 { 119*67e74705SXin Li D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} 120*67e74705SXin Li InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}} 121*67e74705SXin Li }; 122*67e74705SXin Li struct D7 { 123*67e74705SXin Li const Trivial a; // expected-note 3{{field 'a' has no }} 124*67e74705SXin Li }; 125*67e74705SXin Li struct D8 { 126*67e74705SXin Li volatile Trivial a; // expected-note 3{{field 'a' has no }} 127*67e74705SXin Li }; 128*67e74705SXin Li template struct CopyAssign<D1>; // expected-note {{here}} 129*67e74705SXin Li template struct MoveAssign<D2>; // expected-note {{here}} 130*67e74705SXin Li template struct MoveOrCopyAssign<D2>; // expected-note {{here}} 131*67e74705SXin Li template struct CopyAssign<D3>; // expected-note {{here}} 132*67e74705SXin Li template struct MoveAssign<D4>; // expected-note {{here}} 133*67e74705SXin Li template struct MoveOrCopyAssign<D4>; // expected-note {{here}} 134*67e74705SXin Li template struct CopyAssign<D5>; // expected-note {{here}} 135*67e74705SXin Li template struct MoveAssign<D6>; // expected-note {{here}} 136*67e74705SXin Li template struct MoveOrCopyAssign<D6>; // expected-note {{here}} 137*67e74705SXin Li template struct CopyAssign<D7>; // expected-note {{here}} 138*67e74705SXin Li template struct MoveAssign<D7>; // expected-note {{here}} 139*67e74705SXin Li template struct MoveOrCopyAssign<D7>; // expected-note {{here}} 140*67e74705SXin Li template struct CopyAssign<D8>; // expected-note {{here}} 141*67e74705SXin Li template struct MoveAssign<D8>; // expected-note {{here}} 142*67e74705SXin Li template struct MoveOrCopyAssign<D8>; // expected-note {{here}} 143*67e74705SXin Li 144*67e74705SXin Li // -- a direct or virtual base that cannot be copied/moved 145*67e74705SXin Li struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}} 146*67e74705SXin Li struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}} 147*67e74705SXin Li E2 &operator=(E2 &&) = default; // expected-note {{here}} 148*67e74705SXin Li }; 149*67e74705SXin Li struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}} 150*67e74705SXin Li struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}} 151*67e74705SXin Li E4 &operator=(E4 &&) = default; // expected-note {{here}} 152*67e74705SXin Li }; 153*67e74705SXin Li struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}} 154*67e74705SXin Li struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}} 155*67e74705SXin Li E6 &operator=(E6 &&) = default; // expected-note {{here}} 156*67e74705SXin Li }; 157*67e74705SXin Li template struct CopyAssign<E1>; // expected-note {{here}} 158*67e74705SXin Li template struct MoveAssign<E2>; // expected-note {{here}} 159*67e74705SXin Li template struct CopyAssign<E3>; // expected-note {{here}} 160*67e74705SXin Li template struct MoveAssign<E4>; // expected-note {{here}} 161*67e74705SXin Li template struct CopyAssign<E5>; // expected-note {{here}} 162*67e74705SXin Li template struct MoveAssign<E6>; // expected-note {{here}} 163*67e74705SXin Li 164*67e74705SXin Li namespace PR13381 { 165*67e74705SXin Li struct S { 166*67e74705SXin Li S &operator=(const S&); 167*67e74705SXin Li S &operator=(const volatile S&) volatile = delete; // expected-note{{deleted here}} 168*67e74705SXin Li }; 169*67e74705SXin Li struct T { 170*67e74705SXin Li volatile S s; // expected-note{{field 's' has a deleted copy assignment}} 171*67e74705SXin Li }; g()172*67e74705SXin Li void g() { 173*67e74705SXin Li T t; 174*67e74705SXin Li t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}} 175*67e74705SXin Li } 176*67e74705SXin Li } 177*67e74705SXin Li 178*67e74705SXin Li namespace Mutable { 179*67e74705SXin Li struct AmbiguousCopyAssign { 180*67e74705SXin Li AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &); 181*67e74705SXin Li AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &); 182*67e74705SXin Li }; 183*67e74705SXin Li struct X { 184*67e74705SXin Li AmbiguousCopyAssign a; 185*67e74705SXin Li }; 186*67e74705SXin Li struct Y { 187*67e74705SXin Li mutable AmbiguousCopyAssign a; // expected-note {{multiple copy assignment operators}} 188*67e74705SXin Li }; 189*67e74705SXin Li } 190*67e74705SXin Li template struct CopyAssign<Mutable::X>; 191*67e74705SXin Li template struct CopyAssign<Mutable::Y>; // expected-note {{here}} 192