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