192 lines · cpp
1// RUN: %clang_cc1 -verify %s -std=c++11 -Wno-defaulted-function-deleted2 3struct Trivial {};4 5template<typename T> struct CopyAssign {6 static T t;7 void test() {8 t = t; // expected-error +{{deleted}}9 }10};11template<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};19template<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 26struct NonTrivialCopyAssign {27 NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);28};29struct NonTrivialMoveAssign {30 NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);31};32struct AmbiguousCopyAssign {33 AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile;34 AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const;35};36struct AmbiguousMoveAssign {37 AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&);38 AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&);39};40struct DeletedCopyAssign {41 DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}}42};43struct DeletedMoveAssign {44 DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}}45};46class InaccessibleCopyAssign {47 InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &);48};49class InaccessibleMoveAssign {50 InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&);51};52class NonConstCopyAssign {53 NonConstCopyAssign &operator=(NonConstCopyAssign &);54};55 56// A defaulted copy/move assignment operator for class X is defined as deleted57// if X has:58 59// -- a variant member with a non-trivial corresponding assignment operator60// and X is a union-like class61struct A1 {62 union {63 NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}}64 };65};66template struct CopyAssign<A1>; // expected-note {{here}}67 68struct 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};74template struct MoveAssign<A2>; // expected-note {{here}}75 76// -- a non-static const data member of (array of) non-class type77struct B1 {78 const int a; // expected-note 2{{field 'a' is of const-qualified type}}79};80struct 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};83struct B3 {84 const void *a[3];85};86template struct CopyAssign<B1>; // expected-note {{here}}87template struct MoveAssign<B1>; // expected-note {{here}}88template struct CopyAssign<B2>; // expected-note {{here}}89template struct MoveAssign<B2>; // expected-note {{here}}90template struct CopyAssign<B3>;91template struct MoveAssign<B3>;92 93// -- a non-static data member of reference type94struct C1 {95 int &a; // expected-note 2{{field 'a' is of reference type 'int &'}}96};97template struct CopyAssign<C1>; // expected-note {{here}}98template struct MoveAssign<C1>; // expected-note {{here}}99 100// -- a non-static data member of class type M that cannot be copied/moved101struct D1 {102 AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}}103};104struct 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};108struct D3 {109 DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}}110};111struct 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};115struct D5 {116 InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}}117};118struct 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};122struct D7 {123 const Trivial a; // expected-note 3{{field 'a' has no }}124};125struct D8 {126 volatile Trivial a; // expected-note 3{{field 'a' has no }}127};128template struct CopyAssign<D1>; // expected-note {{here}}129template struct MoveAssign<D2>; // expected-note {{here}}130template struct MoveOrCopyAssign<D2>; // expected-note {{here}}131template struct CopyAssign<D3>; // expected-note {{here}}132template struct MoveAssign<D4>; // expected-note {{here}}133template struct MoveOrCopyAssign<D4>; // expected-note {{here}}134template struct CopyAssign<D5>; // expected-note {{here}}135template struct MoveAssign<D6>; // expected-note {{here}}136template struct MoveOrCopyAssign<D6>; // expected-note {{here}}137template struct CopyAssign<D7>; // expected-note {{here}}138template struct MoveAssign<D7>; // expected-note {{here}}139template struct MoveOrCopyAssign<D7>; // expected-note {{here}}140template struct CopyAssign<D8>; // expected-note {{here}}141template struct MoveAssign<D8>; // expected-note {{here}}142template struct MoveOrCopyAssign<D8>; // expected-note {{here}}143 144// -- a direct or virtual base that cannot be copied/moved145struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}}146struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}}147 E2 &operator=(E2 &&) = default; // expected-note {{here}}148};149struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}}150struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}}151 E4 &operator=(E4 &&) = default; // expected-note {{here}}152};153struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}}154struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}}155 E6 &operator=(E6 &&) = default; // expected-note {{here}}156};157template struct CopyAssign<E1>; // expected-note {{here}}158template struct MoveAssign<E2>; // expected-note {{here}}159template struct CopyAssign<E3>; // expected-note {{here}}160template struct MoveAssign<E4>; // expected-note {{here}}161template struct CopyAssign<E5>; // expected-note {{here}}162template struct MoveAssign<E6>; // expected-note {{here}}163 164namespace 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 'T' cannot be assigned because its copy assignment operator is implicitly deleted}}175 }176}177 178namespace 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}190template struct CopyAssign<Mutable::X>;191template struct CopyAssign<Mutable::Y>; // expected-note {{here}}192