p23-cxx11.cpp revision 743cbb91499e138a63a398c6515667905f1b3be8
1a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith// RUN: %clang_cc1 -verify %s -std=c++11
2a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
3a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate<typename T> struct CopyAssign {
4a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  static T t;
5a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  void test() {
6a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith    t = t; // expected-error +{{deleted}}
7a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  }
8a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
9a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate<typename T> struct MoveAssign {
10a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  static T t;
11a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  void test() {
12743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    // Overload resolution will ignore a defaulted, deleted move assignment,
13743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    // so check for it in a different way.
14743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}}
15743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  }
16743cbb91499e138a63a398c6515667905f1b3be8Richard Smith};
17743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate<typename T> struct MoveOrCopyAssign {
18743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  static T t;
19743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  void test() {
20743cbb91499e138a63a398c6515667905f1b3be8Richard Smith    t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}}
21a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  }
22a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
23a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
24a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct NonTrivialCopyAssign {
25a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
26a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
27a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct NonTrivialMoveAssign {
28a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
29a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
30a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct AmbiguousCopyAssign {
31a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &);
32a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &);
33a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
34a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct AmbiguousMoveAssign {
35a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&);
36a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&);
37a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
38a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct DeletedCopyAssign {
39a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}}
40a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
41a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct DeletedMoveAssign {
42a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}}
43a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
44a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithclass InaccessibleCopyAssign {
45a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &);
46a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
47a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithclass InaccessibleMoveAssign {
48a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&);
49a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
50a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
51a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith// A defaulted copy/move assignment operator for class X is defined as deleted
52a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith// if X has:
53a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
54a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a variant member with a non-trivial corresponding assignment operator
55a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//      and X is a union-like class
56a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct A1 {
57a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  union {
58a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith    NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}}
59a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  };
60a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
61a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<A1>; // expected-note {{here}}
62a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
63a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct A2 {
64a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  A2 &operator=(A2 &&) = default; // expected-note {{here}}
65a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  union {
66a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith    NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}}
67a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  };
68a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
69a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<A2>; // expected-note {{here}}
70a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
71a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a non-static const data member of (array of) non-class type
72a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct B1 {
73a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  const int a; // expected-note 2{{field 'a' is of const-qualified type}}
74a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
75a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct B2 {
76a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}}
77a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
78a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct B3 {
79a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  const void *a[3];
80a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
81a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<B1>; // expected-note {{here}}
82a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<B1>; // expected-note {{here}}
83a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<B2>; // expected-note {{here}}
84a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<B2>; // expected-note {{here}}
85a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<B3>;
86a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<B3>;
87a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
88a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a non-static data member of reference type
89a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct C1 {
90a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  int &a; // expected-note 2{{field 'a' is of reference type 'int &'}}
91a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
92a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<C1>; // expected-note {{here}}
93a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<C1>; // expected-note {{here}}
94a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
95a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a non-static data member of class type M that cannot be copied/moved
96a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D1 {
97a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}}
98a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
99a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D2 {
100743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
101a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}}
102a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
103a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D3 {
104a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}}
105a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
106a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D4 {
107743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
108a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}}
109a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
110a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D5 {
111a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}}
112a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
113a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct D6 {
114743cbb91499e138a63a398c6515667905f1b3be8Richard Smith  D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
115a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}}
116a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
117a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<D1>; // expected-note {{here}}
118a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<D2>; // expected-note {{here}}
119743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate struct MoveOrCopyAssign<D2>; // expected-note {{here}}
120a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<D3>; // expected-note {{here}}
121a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<D4>; // expected-note {{here}}
122743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate struct MoveOrCopyAssign<D4>; // expected-note {{here}}
123a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<D5>; // expected-note {{here}}
124a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<D6>; // expected-note {{here}}
125743cbb91499e138a63a398c6515667905f1b3be8Richard Smithtemplate struct MoveOrCopyAssign<D6>; // expected-note {{here}}
126a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith
127a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith//   -- a direct or virtual base that cannot be copied/moved
128a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}}
129a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}}
130a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  E2 &operator=(E2 &&) = default; // expected-note {{here}}
131a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
132a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}}
133a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}}
134a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  E4 &operator=(E4 &&) = default; // expected-note {{here}}
135a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
136a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}}
137a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithstruct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}}
138a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith  E6 &operator=(E6 &&) = default; // expected-note {{here}}
139a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smith};
140a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<E1>; // expected-note {{here}}
141a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<E2>; // expected-note {{here}}
142a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<E3>; // expected-note {{here}}
143a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<E4>; // expected-note {{here}}
144a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct CopyAssign<E5>; // expected-note {{here}}
145a2e76f56c60dbd4de3dc0fed02bb01bea4dcff81Richard Smithtemplate struct MoveAssign<E6>; // expected-note {{here}}
146517bb844016064f303416f09f1aeb123e32c0f66Richard Smith
147517bb844016064f303416f09f1aeb123e32c0f66Richard Smithnamespace PR13381 {
148517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  struct S {
149517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    S &operator=(const S&);
150517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    S &operator=(const volatile S&) = delete; // expected-note{{deleted here}}
151517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  };
152517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  struct T {
153517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    volatile S s; // expected-note{{field 's' has a deleted copy assignment}}
154517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  };
155517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  void g() {
156517bb844016064f303416f09f1aeb123e32c0f66Richard Smith    T t;
1570f46e64947bdd570a499732c4b459961627d8745Richard Smith    t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}}
158517bb844016064f303416f09f1aeb123e32c0f66Richard Smith  }
159517bb844016064f303416f09f1aeb123e32c0f66Richard Smith}
160