1a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith// RUN: %clang_cc1 -verify %s -std=c++11
2a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
37bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingstruct Trivial {};
47bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling
5a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate<typename T> struct CopyAssign {
6a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  static T t;
7a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  void test() {
8a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith    t = t; // expected-error +{{deleted}}
9a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  }
10a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
11a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate<typename T> struct MoveAssign {
12a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  static T t;
13a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  void test() {
14743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    // Overload resolution will ignore a defaulted, deleted move assignment,
15743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    // so check for it in a different way.
16743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}}
17743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  }
18743cbb91499e138a63a398c6515667905f1b3be8Richard Smith};
19743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate<typename T> struct MoveOrCopyAssign {
20743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  static T t;
21743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  void test() {
22743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}}
23a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  }
24a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
25a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
26a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct NonTrivialCopyAssign {
27a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
28a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
29a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct NonTrivialMoveAssign {
30a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
31a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
32a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct AmbiguousCopyAssign {
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile;
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const;
35a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
36a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct AmbiguousMoveAssign {
37a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&);
38a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&);
39a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
40a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct DeletedCopyAssign {
41a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}}
42a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
43a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct DeletedMoveAssign {
44a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}}
45a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
46a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithclass InaccessibleCopyAssign {
47a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &);
48a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
49a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithclass InaccessibleMoveAssign {
50a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&);
51a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
527bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingclass NonConstCopyAssign {
537bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling  NonConstCopyAssign &operator=(NonConstCopyAssign &);
547bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling};
55a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
56a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith// A defaulted copy/move assignment operator for class X is defined as deleted
57a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith// if X has:
58a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
59a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a variant member with a non-trivial corresponding assignment operator
60a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//      and X is a union-like class
61a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct A1 {
62a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  union {
63a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith    NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}}
64a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  };
65a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
66a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<A1>; // expected-note {{here}}
67a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
68a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct A2 {
69a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  A2 &operator=(A2 &&) = default; // expected-note {{here}}
70a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  union {
71a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith    NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}}
72a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  };
73a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
74a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<A2>; // expected-note {{here}}
75a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
76a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a non-static const data member of (array of) non-class type
77a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct B1 {
78a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  const int a; // expected-note 2{{field 'a' is of const-qualified type}}
79a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
80a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct B2 {
81a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}}
82a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
83a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct B3 {
84a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  const void *a[3];
85a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
86a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<B1>; // expected-note {{here}}
87a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<B1>; // expected-note {{here}}
88a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<B2>; // expected-note {{here}}
89a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<B2>; // expected-note {{here}}
90a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<B3>;
91a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<B3>;
92a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
93a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a non-static data member of reference type
94a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct C1 {
95a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  int &a; // expected-note 2{{field 'a' is of reference type 'int &'}}
96a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
97a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<C1>; // expected-note {{here}}
98a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<C1>; // expected-note {{here}}
99a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
100a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a non-static data member of class type M that cannot be copied/moved
101a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D1 {
102a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}}
103a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
104a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D2 {
105743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
106a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}}
107a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
108a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D3 {
109a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}}
110a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
111a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D4 {
112743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
113a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}}
114a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
115a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D5 {
116a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}}
117a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
118a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D6 {
119743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
120a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}}
121a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
1227bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingstruct D7 {
1237bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling  const Trivial a; // expected-note 3{{field 'a' has no }}
1247bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling};
1257bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingstruct D8 {
1267bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling  volatile Trivial a; // expected-note 3{{field 'a' has no }}
1277bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling};
128a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<D1>; // expected-note {{here}}
129a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<D2>; // expected-note {{here}}
130743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate struct MoveOrCopyAssign<D2>; // expected-note {{here}}
131a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<D3>; // expected-note {{here}}
132a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<D4>; // expected-note {{here}}
133743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate struct MoveOrCopyAssign<D4>; // expected-note {{here}}
134a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<D5>; // expected-note {{here}}
135a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<D6>; // expected-note {{here}}
136743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate struct MoveOrCopyAssign<D6>; // expected-note {{here}}
1377bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingtemplate struct CopyAssign<D7>; // expected-note {{here}}
1387bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingtemplate struct MoveAssign<D7>; // expected-note {{here}}
1397bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingtemplate struct MoveOrCopyAssign<D7>; // expected-note {{here}}
1407bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingtemplate struct CopyAssign<D8>; // expected-note {{here}}
1417bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingtemplate struct MoveAssign<D8>; // expected-note {{here}}
1427bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendlingtemplate struct MoveOrCopyAssign<D8>; // expected-note {{here}}
143a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
144a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a direct or virtual base that cannot be copied/moved
145a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}}
146a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}}
147a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  E2 &operator=(E2 &&) = default; // expected-note {{here}}
148a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
149a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}}
150a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}}
151a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  E4 &operator=(E4 &&) = default; // expected-note {{here}}
152a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
153a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}}
154a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}}
155a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  E6 &operator=(E6 &&) = default; // expected-note {{here}}
156a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
157a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<E1>; // expected-note {{here}}
158a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<E2>; // expected-note {{here}}
159a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<E3>; // expected-note {{here}}
160a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<E4>; // expected-note {{here}}
161a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<E5>; // expected-note {{here}}
162a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<E6>; // expected-note {{here}}
163517bb844016064f303416f09f1aeb123e32c0f66Richard Smith
164517bb844016064f303416f09f1aeb123e32c0f66Richard Smithnamespace PR13381 {
165517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  struct S {
166517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    S &operator=(const S&);
1677bd67854cfa59699e0efe72244af1578f2a1c09eBill Wendling    S &operator=(const volatile S&) volatile = delete; // expected-note{{deleted here}}
168517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  };
169517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  struct T {
170517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    volatile S s; // expected-note{{field 's' has a deleted copy assignment}}
171517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  };
172517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  void g() {
173517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    T t;
1740f46e64947bdd570a499732c4b459961627d8745Richard Smith    t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}}
175517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  }
176517bb844016064f303416f09f1aeb123e32c0f66Richard Smith}
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace Mutable {
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct AmbiguousCopyAssign {
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &);
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &);
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct X {
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    AmbiguousCopyAssign a;
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct Y {
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mutable AmbiguousCopyAssign a; // expected-note {{multiple copy assignment operators}}
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate struct CopyAssign<Mutable::X>;
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate struct CopyAssign<Mutable::Y>; // expected-note {{here}}
192