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