p23-cxx11.cpp revision 743cbb91499e138a63a398c6515667905f1b3be8
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// RUN: %clang_cc1 -verify %s -std=c++11 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutemplate<typename T> struct CopyAssign { 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static T t; 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void test() { 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu t = t; // expected-error +{{deleted}} 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutemplate<typename T> struct MoveAssign { 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static T t; 110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void test() { 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Overload resolution will ignore a defaulted, deleted move assignment, 135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // so check for it in a different way. 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}} 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutemplate<typename T> struct MoveOrCopyAssign { 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static T t; 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void test() { 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}} 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct NonTrivialCopyAssign { 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &); 265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct NonTrivialMoveAssign { 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&); 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct AmbiguousCopyAssign { 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &); 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &); 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct AmbiguousMoveAssign { 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&); 36 AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&); 37}; 38struct DeletedCopyAssign { 39 DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}} 40}; 41struct DeletedMoveAssign { 42 DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}} 43}; 44class InaccessibleCopyAssign { 45 InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &); 46}; 47class InaccessibleMoveAssign { 48 InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&); 49}; 50 51// A defaulted copy/move assignment operator for class X is defined as deleted 52// if X has: 53 54// -- a variant member with a non-trivial corresponding assignment operator 55// and X is a union-like class 56struct A1 { 57 union { 58 NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}} 59 }; 60}; 61template struct CopyAssign<A1>; // expected-note {{here}} 62 63struct A2 { 64 A2 &operator=(A2 &&) = default; // expected-note {{here}} 65 union { 66 NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}} 67 }; 68}; 69template struct MoveAssign<A2>; // expected-note {{here}} 70 71// -- a non-static const data member of (array of) non-class type 72struct B1 { 73 const int a; // expected-note 2{{field 'a' is of const-qualified type}} 74}; 75struct B2 { 76 const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}} 77}; 78struct B3 { 79 const void *a[3]; 80}; 81template struct CopyAssign<B1>; // expected-note {{here}} 82template struct MoveAssign<B1>; // expected-note {{here}} 83template struct CopyAssign<B2>; // expected-note {{here}} 84template struct MoveAssign<B2>; // expected-note {{here}} 85template struct CopyAssign<B3>; 86template struct MoveAssign<B3>; 87 88// -- a non-static data member of reference type 89struct C1 { 90 int &a; // expected-note 2{{field 'a' is of reference type 'int &'}} 91}; 92template struct CopyAssign<C1>; // expected-note {{here}} 93template struct MoveAssign<C1>; // expected-note {{here}} 94 95// -- a non-static data member of class type M that cannot be copied/moved 96struct D1 { 97 AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}} 98}; 99struct D2 { 100 D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} 101 AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}} 102}; 103struct D3 { 104 DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}} 105}; 106struct D4 { 107 D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} 108 DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}} 109}; 110struct D5 { 111 InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}} 112}; 113struct D6 { 114 D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}} 115 InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}} 116}; 117template struct CopyAssign<D1>; // expected-note {{here}} 118template struct MoveAssign<D2>; // expected-note {{here}} 119template struct MoveOrCopyAssign<D2>; // expected-note {{here}} 120template struct CopyAssign<D3>; // expected-note {{here}} 121template struct MoveAssign<D4>; // expected-note {{here}} 122template struct MoveOrCopyAssign<D4>; // expected-note {{here}} 123template struct CopyAssign<D5>; // expected-note {{here}} 124template struct MoveAssign<D6>; // expected-note {{here}} 125template struct MoveOrCopyAssign<D6>; // expected-note {{here}} 126 127// -- a direct or virtual base that cannot be copied/moved 128struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}} 129struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}} 130 E2 &operator=(E2 &&) = default; // expected-note {{here}} 131}; 132struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}} 133struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}} 134 E4 &operator=(E4 &&) = default; // expected-note {{here}} 135}; 136struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}} 137struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}} 138 E6 &operator=(E6 &&) = default; // expected-note {{here}} 139}; 140template struct CopyAssign<E1>; // expected-note {{here}} 141template struct MoveAssign<E2>; // expected-note {{here}} 142template struct CopyAssign<E3>; // expected-note {{here}} 143template struct MoveAssign<E4>; // expected-note {{here}} 144template struct CopyAssign<E5>; // expected-note {{here}} 145template struct MoveAssign<E6>; // expected-note {{here}} 146 147namespace PR13381 { 148 struct S { 149 S &operator=(const S&); 150 S &operator=(const volatile S&) = delete; // expected-note{{deleted here}} 151 }; 152 struct T { 153 volatile S s; // expected-note{{field 's' has a deleted copy assignment}} 154 }; 155 void g() { 156 T t; 157 t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}} 158 } 159} 160