1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
3 // Tests for implicit (non-)declaration of move constructor and
4 // assignment: p9, p11, p20, p23.
6 // This class, used as a member, allows to distinguish move from copy because
7 // move operations are no-throw, copy operations aren't.
9 ThrowingCopy() noexcept;
10 ThrowingCopy(ThrowingCopy &&) noexcept;
11 ThrowingCopy(const ThrowingCopy &) noexcept(false);
12 ThrowingCopy & operator =(ThrowingCopy &&) noexcept;
13 ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false);
16 struct HasCopyConstructor {
18 HasCopyConstructor() noexcept;
19 HasCopyConstructor(const HasCopyConstructor &) noexcept(false);
22 struct HasCopyAssignment {
24 HasCopyAssignment() noexcept;
25 HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
28 struct HasMoveConstructor {
30 HasMoveConstructor() noexcept;
31 HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
34 struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
36 HasMoveAssignment() noexcept;
37 HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept;
40 struct HasDestructor {
42 HasDestructor() noexcept;
43 ~HasDestructor() noexcept;
46 void test_basic_exclusion() {
47 static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), "");
48 HasCopyConstructor hcc;
49 static_assert(!noexcept(hcc = HasCopyConstructor()), "");
51 static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), "");
52 HasCopyAssignment hca;
53 static_assert(!noexcept(hca = HasCopyAssignment()), "");
55 static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
56 HasMoveConstructor hmc;
57 hmc = HasMoveConstructor(); // expected-error {{object of type 'HasMoveConstructor' cannot be assigned because its copy assignment operator is implicitly deleted}}
59 (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
60 HasMoveAssignment hma;
61 static_assert(noexcept(hma = HasMoveAssignment()), "");
63 static_assert(!noexcept(HasDestructor((HasDestructor()))), "");
65 static_assert(!noexcept(hd = HasDestructor()), "");
69 PrivateMove() noexcept;
70 PrivateMove(const PrivateMove &) noexcept(false);
71 PrivateMove & operator =(const PrivateMove &) noexcept(false);
73 PrivateMove(PrivateMove &&) noexcept;
74 PrivateMove & operator =(PrivateMove &&) noexcept;
77 struct InheritsPrivateMove : PrivateMove {};
78 struct ContainsPrivateMove {
82 struct PrivateDestructor {
83 PrivateDestructor() noexcept;
84 PrivateDestructor(const PrivateDestructor &) noexcept(false);
85 PrivateDestructor(PrivateDestructor &&) noexcept;
87 ~PrivateDestructor() noexcept;
90 struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
91 struct ContainsPrivateDestructor {
92 PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
95 struct NonTrivialCopyOnly {
96 NonTrivialCopyOnly() noexcept;
97 NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false);
98 NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false);
101 struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {};
102 struct ContainsNonTrivialCopyOnly {
103 NonTrivialCopyOnly ntco;
106 struct ContainsConst {
108 ContainsConst() noexcept;
109 ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}}
114 ContainsRef() noexcept;
115 ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}}
119 Base & operator =(Base &);
121 struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}}
122 struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}}
124 void test_deletion_exclusion() {
125 // FIXME: How to test the union thing?
127 static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), "");
128 static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), "");
129 InheritsPrivateMove ipm;
130 static_assert(!noexcept(ipm = InheritsPrivateMove()), "");
131 ContainsPrivateMove cpm;
132 static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
134 (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
135 (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
137 static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
138 static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
139 InheritsNonTrivialCopyOnly intco;
140 static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), "");
141 ContainsNonTrivialCopyOnly cntco;
142 static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), "");
145 cc = ContainsConst(); // expected-error {{no viable}}
148 cr = ContainsRef(); // expected-error {{no viable}}
150 DirectVirtualBase dvb;
151 dvb = DirectVirtualBase(); // expected-error {{no viable}}
153 IndirectVirtualBase ivb;
154 ivb = IndirectVirtualBase(); // expected-error {{no viable}}
157 struct ContainsRValueRef {
159 ContainsRValueRef() noexcept;
162 void test_contains_rref() {
163 (ContainsRValueRef(ContainsRValueRef()));
168 struct NonTrivialCopyCtor {
169 NonTrivialCopyCtor(const NonTrivialCopyCtor &);
171 struct NonTrivialCopyAssign {
172 NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
175 struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
176 NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
177 NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
179 struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
180 NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
181 NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
184 struct NonTrivialMoveAssign {
185 NonTrivialMoveAssign(NonTrivialMoveAssign&&);
186 NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
188 struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
189 NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
190 NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default;
193 // DR1402: A non-movable, non-trivially-copyable class type as a subobject no
194 // longer inhibits the declaration of a move operation.
195 struct NoMove1 { NonTrivialCopyCtor ntcc; };
196 struct NoMove2 { NonTrivialCopyAssign ntcc; };
197 struct NoMove3 : NonTrivialCopyCtor {};
198 struct NoMove4 : NonTrivialCopyAssign {};
199 struct NoMove5 : virtual NonTrivialCopyCtor {};
200 struct NoMove6 : virtual NonTrivialCopyAssign {};
201 struct NoMove7 : NonTrivialCopyCtorVBase {};
202 struct NoMove8 : NonTrivialCopyAssignVBase {};
204 // DR1402: A non-trivially-move-assignable virtual base class no longer
205 // inhibits the declaration of a move assignment (even though it might
206 // move-assign the base class multiple times).
207 struct NoMove9 : NonTrivialMoveAssign {};
208 struct NoMove10 : virtual NonTrivialMoveAssign {};
209 struct NoMove11 : NonTrivialMoveAssignVBase {};
211 template<typename T> void test(T t) {
212 (void)T(static_cast<T&&>(t)); // ok
213 t = static_cast<T&&>(t); // ok
215 template void test(NoMove1);
216 template void test(NoMove2);
217 template void test(NoMove3);
218 template void test(NoMove4);
219 template void test(NoMove5);
220 template void test(NoMove6);
221 template void test(NoMove7);
222 template void test(NoMove8);
223 template void test(NoMove9);
224 template void test(NoMove10);
225 template void test(NoMove11);
228 CopyOnly(const CopyOnly&);
229 CopyOnly &operator=(const CopyOnly&);
232 MoveOnly(MoveOnly&&); // expected-note {{user-declared move}}
233 MoveOnly &operator=(MoveOnly&&);
235 template void test(CopyOnly); // ok, copies
236 template void test(MoveOnly); // ok, moves
237 struct CopyAndMove { // expected-note {{implicitly deleted}}
239 MoveOnly mo; // expected-note {{deleted copy}}
241 template void test(CopyAndMove); // ok, copies co, moves mo
242 void test2(CopyAndMove cm) {
243 (void)CopyAndMove(cm); // expected-error {{deleted}}
244 cm = cm; // expected-error {{deleted}}
247 namespace VbaseMove {
249 struct B { B &operator=(B&&); };
250 struct C { C &operator=(const C&); };
253 template<typename T, unsigned I, bool NonTrivialMove = false>
254 struct E : virtual T {};
256 template<typename T, unsigned I>
257 struct E<T, I, true> : virtual T { E &operator=(E&&); };
261 E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}}
262 E<T, 1> {}; // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}}
265 struct G : E<T, 0, true>, E<T, 0> {};
268 struct H : E<T, 0, true>, E<T, 1, true> {};
271 struct I : E<T, 0>, T {};
275 E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}}
276 virtual T {}; // expected-note-re 2{{virtual base class '[BD]' declared here}}
278 template<typename T> void move(T t) { t = static_cast<T&&>(t); }
279 // expected-warning-re@-1 4{{defaulted move assignment operator of .* will move assign virtual base class '[BD]' multiple times}}
280 template void move(F<A>);
281 template void move(F<B>); // expected-note {{in instantiation of}}
282 template void move(F<C>);
283 template void move(F<D>); // expected-note {{in instantiation of}}
284 template void move(G<A>);
285 template void move(G<B>);
286 template void move(G<C>);
287 template void move(G<D>);
288 template void move(H<A>);
289 template void move(H<B>);
290 template void move(H<C>);
291 template void move(H<D>);
292 template void move(I<A>);
293 template void move(I<B>);
294 template void move(I<C>);
295 template void move(I<D>);
296 template void move(J<A>);
297 template void move(J<B>); // expected-note {{in instantiation of}}
298 template void move(J<C>);
299 template void move(J<D>); // expected-note {{in instantiation of}}
304 struct X; // expected-note {{forward decl}}
306 X x; // expected-error {{incomplete}}