1// RUN: %clang_cc1 -verify %s -std=c++11 2 3template<typename T> struct CopyAssign { 4 static T t; 5 void test() { 6 t = t; // expected-error +{{deleted}} 7 } 8}; 9template<typename T> struct MoveAssign { 10 static T t; 11 void test() { 12 t = static_cast<T&&>(t); // expected-error +{{deleted}} 13 } 14}; 15 16struct NonTrivialCopyAssign { 17 NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &); 18}; 19struct NonTrivialMoveAssign { 20 NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&); 21}; 22struct AmbiguousCopyAssign { 23 AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &); 24 AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &); 25}; 26struct AmbiguousMoveAssign { 27 AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&); 28 AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&); 29}; 30struct DeletedCopyAssign { 31 DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}} 32}; 33struct DeletedMoveAssign { 34 DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}} 35}; 36class InaccessibleCopyAssign { 37 InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &); 38}; 39class InaccessibleMoveAssign { 40 InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&); 41}; 42 43// A defaulted copy/move assignment operator for class X is defined as deleted 44// if X has: 45 46// -- a variant member with a non-trivial corresponding assignment operator 47// and X is a union-like class 48struct A1 { 49 union { 50 NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}} 51 }; 52}; 53template struct CopyAssign<A1>; // expected-note {{here}} 54 55struct A2 { 56 A2 &operator=(A2 &&) = default; // expected-note {{here}} 57 union { 58 NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}} 59 }; 60}; 61template struct MoveAssign<A2>; // expected-note {{here}} 62 63// -- a non-static const data member of (array of) non-class type 64struct B1 { 65 const int a; // expected-note 2{{field 'a' is of const-qualified type}} 66}; 67struct B2 { 68 const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}} 69}; 70struct B3 { 71 const void *a[3]; 72}; 73template struct CopyAssign<B1>; // expected-note {{here}} 74template struct MoveAssign<B1>; // expected-note {{here}} 75template struct CopyAssign<B2>; // expected-note {{here}} 76template struct MoveAssign<B2>; // expected-note {{here}} 77template struct CopyAssign<B3>; 78template struct MoveAssign<B3>; 79 80// -- a non-static data member of reference type 81struct C1 { 82 int &a; // expected-note 2{{field 'a' is of reference type 'int &'}} 83}; 84template struct CopyAssign<C1>; // expected-note {{here}} 85template struct MoveAssign<C1>; // expected-note {{here}} 86 87// -- a non-static data member of class type M that cannot be copied/moved 88struct D1 { 89 AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}} 90}; 91struct D2 { 92 D2 &operator=(D2 &&) = default; // expected-note {{here}} 93 AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}} 94}; 95struct D3 { 96 DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}} 97}; 98struct D4 { 99 D4 &operator=(D4 &&) = default; // expected-note {{here}} 100 DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}} 101}; 102struct D5 { 103 InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}} 104}; 105struct D6 { 106 D6 &operator=(D6 &&) = default; // expected-note {{here}} 107 InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}} 108}; 109template struct CopyAssign<D1>; // expected-note {{here}} 110template struct MoveAssign<D2>; // expected-note {{here}} 111template struct CopyAssign<D3>; // expected-note {{here}} 112template struct MoveAssign<D4>; // expected-note {{here}} 113template struct CopyAssign<D5>; // expected-note {{here}} 114template struct MoveAssign<D6>; // expected-note {{here}} 115 116// -- a direct or virtual base that cannot be copied/moved 117struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}} 118struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}} 119 E2 &operator=(E2 &&) = default; // expected-note {{here}} 120}; 121struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}} 122struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}} 123 E4 &operator=(E4 &&) = default; // expected-note {{here}} 124}; 125struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}} 126struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}} 127 E6 &operator=(E6 &&) = default; // expected-note {{here}} 128}; 129template struct CopyAssign<E1>; // expected-note {{here}} 130template struct MoveAssign<E2>; // expected-note {{here}} 131template struct CopyAssign<E3>; // expected-note {{here}} 132template struct MoveAssign<E4>; // expected-note {{here}} 133template struct CopyAssign<E5>; // expected-note {{here}} 134template struct MoveAssign<E6>; // expected-note {{here}} 135 136namespace PR13381 { 137 struct S { 138 S &operator=(const S&); 139 S &operator=(const volatile S&) = delete; // expected-note{{deleted here}} 140 }; 141 struct T { 142 volatile S s; // expected-note{{field 's' has a deleted copy assignment}} 143 }; 144 void g() { 145 T t; 146 t = T(); // expected-error{{implicitly-deleted copy assignment}} 147 } 148} 149