xref: /aosp_15_r20/external/clang/test/CXX/special/class.copy/p23-cxx11.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -verify %s -std=c++11
2*67e74705SXin Li 
3*67e74705SXin Li struct Trivial {};
4*67e74705SXin Li 
5*67e74705SXin Li template<typename T> struct CopyAssign {
6*67e74705SXin Li   static T t;
testCopyAssign7*67e74705SXin Li   void test() {
8*67e74705SXin Li     t = t; // expected-error +{{deleted}}
9*67e74705SXin Li   }
10*67e74705SXin Li };
11*67e74705SXin Li template<typename T> struct MoveAssign {
12*67e74705SXin Li   static T t;
testMoveAssign13*67e74705SXin Li   void test() {
14*67e74705SXin Li     // Overload resolution will ignore a defaulted, deleted move assignment,
15*67e74705SXin Li     // so check for it in a different way.
16*67e74705SXin Li     T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}}
17*67e74705SXin Li   }
18*67e74705SXin Li };
19*67e74705SXin Li template<typename T> struct MoveOrCopyAssign {
20*67e74705SXin Li   static T t;
testMoveOrCopyAssign21*67e74705SXin Li   void test() {
22*67e74705SXin Li     t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}}
23*67e74705SXin Li   }
24*67e74705SXin Li };
25*67e74705SXin Li 
26*67e74705SXin Li struct NonTrivialCopyAssign {
27*67e74705SXin Li   NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
28*67e74705SXin Li };
29*67e74705SXin Li struct NonTrivialMoveAssign {
30*67e74705SXin Li   NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
31*67e74705SXin Li };
32*67e74705SXin Li struct AmbiguousCopyAssign {
33*67e74705SXin Li   AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile;
34*67e74705SXin Li   AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const;
35*67e74705SXin Li };
36*67e74705SXin Li struct AmbiguousMoveAssign {
37*67e74705SXin Li   AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&);
38*67e74705SXin Li   AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&);
39*67e74705SXin Li };
40*67e74705SXin Li struct DeletedCopyAssign {
41*67e74705SXin Li   DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}}
42*67e74705SXin Li };
43*67e74705SXin Li struct DeletedMoveAssign {
44*67e74705SXin Li   DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}}
45*67e74705SXin Li };
46*67e74705SXin Li class InaccessibleCopyAssign {
47*67e74705SXin Li   InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &);
48*67e74705SXin Li };
49*67e74705SXin Li class InaccessibleMoveAssign {
50*67e74705SXin Li   InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&);
51*67e74705SXin Li };
52*67e74705SXin Li class NonConstCopyAssign {
53*67e74705SXin Li   NonConstCopyAssign &operator=(NonConstCopyAssign &);
54*67e74705SXin Li };
55*67e74705SXin Li 
56*67e74705SXin Li // A defaulted copy/move assignment operator for class X is defined as deleted
57*67e74705SXin Li // if X has:
58*67e74705SXin Li 
59*67e74705SXin Li //   -- a variant member with a non-trivial corresponding assignment operator
60*67e74705SXin Li //      and X is a union-like class
61*67e74705SXin Li struct A1 {
62*67e74705SXin Li   union {
63*67e74705SXin Li     NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}}
64*67e74705SXin Li   };
65*67e74705SXin Li };
66*67e74705SXin Li template struct CopyAssign<A1>; // expected-note {{here}}
67*67e74705SXin Li 
68*67e74705SXin Li struct A2 {
69*67e74705SXin Li   A2 &operator=(A2 &&) = default; // expected-note {{here}}
70*67e74705SXin Li   union {
71*67e74705SXin Li     NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}}
72*67e74705SXin Li   };
73*67e74705SXin Li };
74*67e74705SXin Li template struct MoveAssign<A2>; // expected-note {{here}}
75*67e74705SXin Li 
76*67e74705SXin Li //   -- a non-static const data member of (array of) non-class type
77*67e74705SXin Li struct B1 {
78*67e74705SXin Li   const int a; // expected-note 2{{field 'a' is of const-qualified type}}
79*67e74705SXin Li };
80*67e74705SXin Li struct B2 {
81*67e74705SXin Li   const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}}
82*67e74705SXin Li };
83*67e74705SXin Li struct B3 {
84*67e74705SXin Li   const void *a[3];
85*67e74705SXin Li };
86*67e74705SXin Li template struct CopyAssign<B1>; // expected-note {{here}}
87*67e74705SXin Li template struct MoveAssign<B1>; // expected-note {{here}}
88*67e74705SXin Li template struct CopyAssign<B2>; // expected-note {{here}}
89*67e74705SXin Li template struct MoveAssign<B2>; // expected-note {{here}}
90*67e74705SXin Li template struct CopyAssign<B3>;
91*67e74705SXin Li template struct MoveAssign<B3>;
92*67e74705SXin Li 
93*67e74705SXin Li //   -- a non-static data member of reference type
94*67e74705SXin Li struct C1 {
95*67e74705SXin Li   int &a; // expected-note 2{{field 'a' is of reference type 'int &'}}
96*67e74705SXin Li };
97*67e74705SXin Li template struct CopyAssign<C1>; // expected-note {{here}}
98*67e74705SXin Li template struct MoveAssign<C1>; // expected-note {{here}}
99*67e74705SXin Li 
100*67e74705SXin Li //   -- a non-static data member of class type M that cannot be copied/moved
101*67e74705SXin Li struct D1 {
102*67e74705SXin Li   AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}}
103*67e74705SXin Li };
104*67e74705SXin Li struct D2 {
105*67e74705SXin Li   D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
106*67e74705SXin Li   AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}}
107*67e74705SXin Li };
108*67e74705SXin Li struct D3 {
109*67e74705SXin Li   DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}}
110*67e74705SXin Li };
111*67e74705SXin Li struct D4 {
112*67e74705SXin Li   D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
113*67e74705SXin Li   DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}}
114*67e74705SXin Li };
115*67e74705SXin Li struct D5 {
116*67e74705SXin Li   InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}}
117*67e74705SXin Li };
118*67e74705SXin Li struct D6 {
119*67e74705SXin Li   D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
120*67e74705SXin Li   InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}}
121*67e74705SXin Li };
122*67e74705SXin Li struct D7 {
123*67e74705SXin Li   const Trivial a; // expected-note 3{{field 'a' has no }}
124*67e74705SXin Li };
125*67e74705SXin Li struct D8 {
126*67e74705SXin Li   volatile Trivial a; // expected-note 3{{field 'a' has no }}
127*67e74705SXin Li };
128*67e74705SXin Li template struct CopyAssign<D1>; // expected-note {{here}}
129*67e74705SXin Li template struct MoveAssign<D2>; // expected-note {{here}}
130*67e74705SXin Li template struct MoveOrCopyAssign<D2>; // expected-note {{here}}
131*67e74705SXin Li template struct CopyAssign<D3>; // expected-note {{here}}
132*67e74705SXin Li template struct MoveAssign<D4>; // expected-note {{here}}
133*67e74705SXin Li template struct MoveOrCopyAssign<D4>; // expected-note {{here}}
134*67e74705SXin Li template struct CopyAssign<D5>; // expected-note {{here}}
135*67e74705SXin Li template struct MoveAssign<D6>; // expected-note {{here}}
136*67e74705SXin Li template struct MoveOrCopyAssign<D6>; // expected-note {{here}}
137*67e74705SXin Li template struct CopyAssign<D7>; // expected-note {{here}}
138*67e74705SXin Li template struct MoveAssign<D7>; // expected-note {{here}}
139*67e74705SXin Li template struct MoveOrCopyAssign<D7>; // expected-note {{here}}
140*67e74705SXin Li template struct CopyAssign<D8>; // expected-note {{here}}
141*67e74705SXin Li template struct MoveAssign<D8>; // expected-note {{here}}
142*67e74705SXin Li template struct MoveOrCopyAssign<D8>; // expected-note {{here}}
143*67e74705SXin Li 
144*67e74705SXin Li //   -- a direct or virtual base that cannot be copied/moved
145*67e74705SXin Li struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}}
146*67e74705SXin Li struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}}
147*67e74705SXin Li   E2 &operator=(E2 &&) = default; // expected-note {{here}}
148*67e74705SXin Li };
149*67e74705SXin Li struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}}
150*67e74705SXin Li struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}}
151*67e74705SXin Li   E4 &operator=(E4 &&) = default; // expected-note {{here}}
152*67e74705SXin Li };
153*67e74705SXin Li struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}}
154*67e74705SXin Li struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}}
155*67e74705SXin Li   E6 &operator=(E6 &&) = default; // expected-note {{here}}
156*67e74705SXin Li };
157*67e74705SXin Li template struct CopyAssign<E1>; // expected-note {{here}}
158*67e74705SXin Li template struct MoveAssign<E2>; // expected-note {{here}}
159*67e74705SXin Li template struct CopyAssign<E3>; // expected-note {{here}}
160*67e74705SXin Li template struct MoveAssign<E4>; // expected-note {{here}}
161*67e74705SXin Li template struct CopyAssign<E5>; // expected-note {{here}}
162*67e74705SXin Li template struct MoveAssign<E6>; // expected-note {{here}}
163*67e74705SXin Li 
164*67e74705SXin Li namespace PR13381 {
165*67e74705SXin Li   struct S {
166*67e74705SXin Li     S &operator=(const S&);
167*67e74705SXin Li     S &operator=(const volatile S&) volatile = delete; // expected-note{{deleted here}}
168*67e74705SXin Li   };
169*67e74705SXin Li   struct T {
170*67e74705SXin Li     volatile S s; // expected-note{{field 's' has a deleted copy assignment}}
171*67e74705SXin Li   };
g()172*67e74705SXin Li   void g() {
173*67e74705SXin Li     T t;
174*67e74705SXin Li     t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}}
175*67e74705SXin Li   }
176*67e74705SXin Li }
177*67e74705SXin Li 
178*67e74705SXin Li namespace Mutable {
179*67e74705SXin Li   struct AmbiguousCopyAssign {
180*67e74705SXin Li     AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &);
181*67e74705SXin Li     AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &);
182*67e74705SXin Li   };
183*67e74705SXin Li   struct X {
184*67e74705SXin Li     AmbiguousCopyAssign a;
185*67e74705SXin Li   };
186*67e74705SXin Li   struct Y {
187*67e74705SXin Li     mutable AmbiguousCopyAssign a; // expected-note {{multiple copy assignment operators}}
188*67e74705SXin Li   };
189*67e74705SXin Li }
190*67e74705SXin Li template struct CopyAssign<Mutable::X>;
191*67e74705SXin Li template struct CopyAssign<Mutable::Y>; // expected-note {{here}}
192