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