xref: /llvm-project/clang/test/CXX/class/class.init/class.copy.elision/p3.cpp (revision ba15d186e5cef2620d562c6c9d9a6d570382cd0a)
1 // RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions                       -verify=expected,cxx11_23,cxx23    %s
2 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions                       -verify=expected,cxx98_20,cxx11_23,cxx11_20 %s
3 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fcxx-exceptions                       -verify=expected,cxx98_20,cxx11_23,cxx11_20 %s
4 // RUN: %clang_cc1 -std=c++98 -fsyntax-only -fcxx-exceptions -Wno-c++11-extensions -verify=expected,cxx98_20,cxx98 %s
5 
6 namespace test_delete_function {
7 struct A1 {
8   A1();
9   A1(const A1 &);
10   A1(A1 &&) = delete; // expected-note {{'A1' has been explicitly marked deleted here}}
11 };
test1()12 A1 test1() {
13   A1 a;
14   return a; // expected-error {{call to deleted constructor of 'A1'}}
15 }
16 
17 struct A2 {
18   A2();
19   A2(const A2 &);
20 
21 private:
22   A2(A2 &&); // expected-note {{declared private here}}
23 };
test2()24 A2 test2() {
25   A2 a;
26   return a; // expected-error {{calling a private constructor of class 'test_delete_function::A2'}}
27 }
28 
29 struct C {};
30 
31 struct B1 {
32   B1(C &);
33   B1(C &&) = delete; // expected-note {{'B1' has been explicitly marked deleted here}}
34 };
test3()35 B1 test3() {
36   C c;
37   return c; // expected-error {{conversion function from 'C' to 'B1' invokes a deleted function}}
38 }
39 
40 struct B2 {
41   B2(C &);
42 
43 private:
44   B2(C &&); // expected-note {{declared private here}}
45 };
test4()46 B2 test4() {
47   C c;
48   return c; // expected-error {{calling a private constructor of class 'test_delete_function::B2'}}
49 }
50 } // namespace test_delete_function
51 
52 // Implicitly movable entity can be rvalue reference to non-volatile
53 // automatic object.
54 namespace test_implicitly_movable_rvalue_ref {
55 struct A1 {
56   A1(A1 &&);
57   A1(const A1 &) = delete;
58 };
test1(A1 && a)59 A1 test1(A1 &&a) {
60   return a;
61 }
62 
63 struct A2 {
64   A2(A2 &&);
65 
66 private:
67   A2(const A2 &);
68 };
test2(A2 && a)69 A2 test2(A2 &&a) {
70   return a;
71 }
72 
73 struct B1 {
74   B1(const B1 &);
75   B1(B1 &&) = delete; // expected-note {{'B1' has been explicitly marked deleted here}}
76 };
test3(B1 && b)77 B1 test3(B1 &&b) {
78   return b; // expected-error {{call to deleted constructor of 'B1'}}
79 }
80 
81 struct B2 {
82   B2(const B2 &);
83 
84 private:
85   B2(B2 &&); // expected-note {{declared private here}}
86 };
test4(B2 && b)87 B2 test4(B2 &&b) {
88   return b; // expected-error {{calling a private constructor of class 'test_implicitly_movable_rvalue_ref::B2'}}
89 }
90 } // namespace test_implicitly_movable_rvalue_ref
91 
92 // Operand of throw-expression can be function parameter or
93 // catch-clause parameter.
94 namespace test_throw_parameter {
95 void func();
96 
97 struct A1 {
98   A1(const A1 &);
99   A1(A1 &&) = delete;
100   // expected-note@-1 2{{'A1' has been explicitly marked deleted here}}
101   // cxx11_23-note@-2 3{{'A1' has been explicitly marked deleted here}}
102 };
test1()103 void test1() {
104   try {
105     func();
106   } catch (A1 a) {
107     throw a; // expected-error {{call to deleted constructor of 'A1'}}
108   }
109 }
110 
111 struct A2 {
112   A2(const A2 &);
113 
114 private:
115   A2(A2 &&); // expected-note {{declared private here}}
116 };
test2()117 void test2() {
118   try {
119     func();
120   } catch (A2 a) {
121     throw a; // expected-error {{calling a private constructor of class 'test_throw_parameter::A2'}}
122   }
123 }
124 
test3(A1 a)125 void test3(A1 a) try {
126   func();
127 } catch (...) {
128   throw a; // expected-error {{call to deleted constructor of 'A1'}}
129 }
130 
131 #if __cplusplus >= 201103L
132 namespace PR54341 {
test4(A1 a)133 void test4(A1 a) {
134   void f(decltype((throw a, 0)));
135   // expected-error@-1 {{call to deleted constructor of 'A1'}}
136 
137   void g(int = decltype(throw a, 0){});
138   // expected-error@-1 {{call to deleted constructor of 'A1'}}
139 }
140 
test5(A1 a,int=decltype(throw a,0) {})141 void test5(A1 a, int = decltype(throw a, 0){}) {}
142 // expected-error@-1 {{call to deleted constructor of 'A1'}}
143 } // namespace PR54341
144 #endif
145 
146 } // namespace test_throw_parameter
147 
148 // During the first overload resolution, the selected function no
149 // need to be a constructor.
150 namespace test_non_ctor_conversion {
151 class C {};
152 
153 struct A1 {
154   operator C() &&;
155   operator C() const & = delete;
156 };
test1()157 C test1() {
158   A1 a;
159   return a;
160 }
161 
162 struct A2 {
163   operator C() &&;
164 
165 private:
166   operator C() const &;
167 };
test2()168 C test2() {
169   A2 a;
170   return a;
171 }
172 
173 struct B1 {
174   operator C() const &;
175   operator C() && = delete; // expected-note {{'operator C' has been explicitly marked deleted here}}
176 };
test3()177 C test3() {
178   B1 b;
179   return b; // expected-error {{conversion function from 'B1' to 'C' invokes a deleted function}}
180 }
181 
182 struct B2 {
183   operator C() const &;
184 
185 private:
186   operator C() &&; // expected-note {{declared private here}}
187 };
test4()188 C test4() {
189   B2 b;
190   return b; // expected-error {{'operator C' is a private member of 'test_non_ctor_conversion::B2'}}
191 }
192 } // namespace test_non_ctor_conversion
193 
194 // During the first overload resolution, the first parameter of the
195 // selected function no need to be an rvalue reference to the object's type.
196 namespace test_ctor_param_rvalue_ref {
197 struct A1;
198 struct A2;
199 struct B1;
200 struct B2;
201 
202 struct NeedRvalueRef {
203   NeedRvalueRef(A1 &&);
204   NeedRvalueRef(A2 &&);
205   NeedRvalueRef(B1 &&);
206   NeedRvalueRef(B2 &&);
207 };
208 struct NeedValue {
209   NeedValue(A1); // cxx98-note 2 {{passing argument to parameter here}}
210   NeedValue(A2);
211   NeedValue(B1); // cxx11_23-note 2 {{passing argument to parameter here}}
212   NeedValue(B2);
213 };
214 
215 struct A1 {
216   A1();
217   A1(A1 &&);
218   A1(const A1 &) = delete; // cxx98-note 2 {{marked deleted here}}
219 };
test_1_1()220 NeedValue test_1_1() {
221   // not rvalue reference
222   // same type
223   A1 a;
224   return a; // cxx98-error {{call to deleted constructor}}
225 }
226 class DerivedA1 : public A1 {};
test_1_2()227 A1 test_1_2() {
228   // rvalue reference
229   // not same type
230   DerivedA1 a;
231   return a;
232 }
test_1_3()233 NeedValue test_1_3() {
234   // not rvalue reference
235   // not same type
236   DerivedA1 a;
237   return a; // cxx98-error {{call to deleted constructor}}
238 }
239 
240 struct A2 {
241   A2();
242   A2(A2 &&);
243 
244 private:
245   A2(const A2 &); // cxx98-note 2 {{declared private here}}
246 };
test_2_1()247 NeedValue test_2_1() {
248   // not rvalue reference
249   // same type
250   A2 a;
251   return a; // cxx98-error {{calling a private constructor}}
252 }
253 class DerivedA2 : public A2 {};
test_2_2()254 A2 test_2_2() {
255   // rvalue reference
256   // not same type
257   DerivedA2 a;
258   return a;
259 }
test_2_3()260 NeedValue test_2_3() {
261   // not rvalue reference
262   // not same type
263   DerivedA2 a;
264   return a; // cxx98-error {{calling a private constructor}}
265 }
266 
267 struct B1 {
268   B1();
269   B1(const B1 &);
270   B1(B1 &&) = delete; // cxx11_23-note 3 {{'B1' has been explicitly marked deleted here}}
271                       // cxx98-note@-1 {{'B1' has been explicitly marked deleted here}}
272 };
test_3_1()273 NeedValue test_3_1() {
274   // not rvalue reference
275   // same type
276   B1 b;
277   return b; // cxx11_23-error {{call to deleted constructor of 'B1'}}
278 }
279 class DerivedB1 : public B1 {};
test_3_2()280 B1 test_3_2() {
281   // rvalue reference
282   // not same type
283   DerivedB1 b;
284   return b; // expected-error {{call to deleted constructor of 'B1'}}
285 }
test_3_3()286 NeedValue test_3_3() {
287   // not rvalue reference
288   // not same type
289   DerivedB1 b;
290   return b; // cxx11_23-error {{call to deleted constructor of 'B1'}}
291 }
292 
293 struct B2 {
294   B2();
295   B2(const B2 &);
296 
297 private:
298   B2(B2 &&); // cxx11_23-note 3 {{declared private here}}
299              // cxx98-note@-1 {{declared private here}}
300 };
test_4_1()301 NeedValue test_4_1() {
302   // not rvalue reference
303   // same type
304   B2 b;
305   return b; // cxx11_23-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}}
306 }
307 class DerivedB2 : public B2 {};
test_4_2()308 B2 test_4_2() {
309   // rvalue reference
310   // not same type
311   DerivedB2 b;
312   return b; // expected-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}}
313 }
test_4_3()314 NeedValue test_4_3() {
315   // not rvalue reference
316   // not same type
317   DerivedB2 b;
318   return b; // cxx11_23-error {{calling a private constructor of class 'test_ctor_param_rvalue_ref::B2'}}
319 }
320 } // namespace test_ctor_param_rvalue_ref
321 
322 namespace test_lvalue_ref_is_not_moved_from {
323 
324 struct Target {};
325 // expected-note@-1  {{candidate constructor (the implicit copy constructor) not viable}}
326 // cxx11_23-note@-2  {{candidate constructor (the implicit move constructor) not viable}}
327 
328 struct CopyOnly {
329   CopyOnly(CopyOnly &&) = delete; // expected-note {{has been explicitly marked deleted here}}
330   CopyOnly(CopyOnly&);
331   operator Target() && = delete; // expected-note {{has been explicitly marked deleted here}}
332   operator Target() &;
333 };
334 
335 struct MoveOnly {
336   MoveOnly(MoveOnly &&); // cxx11_23-note {{copy constructor is implicitly deleted because}}
337   operator Target() &&;  // expected-note {{candidate function not viable}}
338 };
339 
340 extern CopyOnly copyonly;
341 extern MoveOnly moveonly;
342 
t1()343 CopyOnly t1() {
344     CopyOnly& r = copyonly;
345     return r;
346 }
347 
t2()348 CopyOnly t2() {
349     CopyOnly&& r = static_cast<CopyOnly&&>(copyonly);
350     return r; // expected-error {{call to deleted constructor}}
351 }
352 
t3()353 MoveOnly t3() {
354     MoveOnly& r = moveonly;
355     return r; // cxx11_23-error {{call to implicitly-deleted copy constructor}}
356 }
357 
t4()358 MoveOnly t4() {
359     MoveOnly&& r = static_cast<MoveOnly&&>(moveonly);
360     return r;
361 }
362 
t5()363 Target t5() {
364     CopyOnly& r = copyonly;
365     return r;
366 }
367 
t6()368 Target t6() {
369     CopyOnly&& r = static_cast<CopyOnly&&>(copyonly);
370     return r; // expected-error {{invokes a deleted function}}
371 }
372 
t7()373 Target t7() {
374     MoveOnly& r = moveonly;
375     return r; // expected-error {{no viable conversion}}
376 }
377 
t8()378 Target t8() {
379     MoveOnly&& r = static_cast<MoveOnly&&>(moveonly);
380     return r;
381 }
382 
383 } // namespace test_lvalue_ref_is_not_moved_from
384 
385 namespace test_rvalue_ref_to_nonobject {
386 
387 struct CopyOnly {};
388 struct MoveOnly {};
389 
390 struct Target {
391     Target(CopyOnly (&)());
392     Target(CopyOnly (&&)()) = delete;
393     Target(MoveOnly (&)()) = delete; // expected-note 2{{has been explicitly marked deleted here}}
394     Target(MoveOnly (&&)());
395 };
396 
397 CopyOnly make_copyonly();
398 MoveOnly make_moveonly();
399 
t1()400 Target t1() {
401     CopyOnly (&r)() = make_copyonly;
402     return r;
403 }
404 
t2()405 Target t2() {
406     CopyOnly (&&r)() = static_cast<CopyOnly(&&)()>(make_copyonly);
407     return r; // OK in all modes; not subject to implicit move
408 }
409 
t3()410 Target t3() {
411     MoveOnly (&r)() = make_moveonly;
412     return r; // expected-error {{invokes a deleted function}}
413 }
414 
t4()415 Target t4() {
416     MoveOnly (&&r)() = static_cast<MoveOnly(&&)()>(make_moveonly);
417     return r; // expected-error {{invokes a deleted function}}
418 }
419 
420 } // namespace test_rvalue_ref_to_nonobject
421 
422 // Both tests in test_constandnonconstcopy, and also test_conversion::test1, are
423 // "pure" C++98 tests (pretend 'delete' means 'private').
424 // However we may extend implicit moves into C++98, we must make sure the
425 // results in these are not changed.
426 namespace test_constandnonconstcopy {
427 struct ConstCopyOnly {
428   ConstCopyOnly();
429   ConstCopyOnly(ConstCopyOnly &) = delete; // cxx98-note {{marked deleted here}}
430   ConstCopyOnly(const ConstCopyOnly &);
431 };
t1()432 ConstCopyOnly t1() {
433   ConstCopyOnly x;
434   return x; // cxx98-error {{call to deleted constructor}}
435 }
436 
437 struct NonConstCopyOnly {
438   NonConstCopyOnly();
439   NonConstCopyOnly(NonConstCopyOnly &);
440   NonConstCopyOnly(const NonConstCopyOnly &) = delete; // cxx11_23-note {{marked deleted here}}
441 };
t2()442 NonConstCopyOnly t2() {
443   NonConstCopyOnly x;
444   return x; // cxx11_23-error {{call to deleted constructor}}
445 }
446 
447 } // namespace test_constandnonconstcopy
448 
449 namespace test_conversion {
450 
451 struct B;
452 struct A {
453   A(B &) = delete; // cxx98-note {{has been explicitly deleted}}
454 };
455 struct B {
456   operator A(); // cxx98-note {{candidate function}}
457 };
test1(B x)458 A test1(B x) { return x; } // cxx98-error-re {{conversion {{.*}} is ambiguous}}
459 
460 struct C {};
461 struct D {
462   operator C() &;
463   operator C() const & = delete; // expected-note {{marked deleted here}}
464 };
test2(D x)465 C test2(D x) { return x; } // expected-error {{invokes a deleted function}}
466 
467 } // namespace test_conversion
468 
469 namespace test_simpler_implicit_move {
470 
471 struct CopyOnly {
472   CopyOnly(); // cxx23-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
473   // cxx23-note@-1 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
474   CopyOnly(CopyOnly &); // cxx23-note {{candidate constructor not viable: expects an lvalue for 1st argument}}
475   // cxx23-note@-1 {{candidate constructor not viable: expects an lvalue for 1st argument}}
476 };
477 struct MoveOnly {
478   MoveOnly();
479   MoveOnly(MoveOnly &&);
480 };
481 MoveOnly &&rref();
482 
test1(MoveOnly && w)483 MoveOnly &&test1(MoveOnly &&w) {
484   return w; // cxx98_20-error {{cannot bind to lvalue of type}}
485 }
486 
test2(bool b)487 CopyOnly test2(bool b) {
488   static CopyOnly w1;
489   CopyOnly w2;
490   if (b) {
491     return w1;
492   } else {
493     return w2; // cxx23-error {{no matching constructor for initialization}}
494   }
495 }
496 
test3(T && x)497 template <class T> T &&test3(T &&x) { return x; } // cxx98_20-error {{cannot bind to lvalue of type}}
498 template MoveOnly& test3<MoveOnly&>(MoveOnly&);
499 template MoveOnly &&test3<MoveOnly>(MoveOnly &&); // cxx98_20-note {{in instantiation of function template specialization}}
500 
test4()501 MoveOnly &&test4() {
502   MoveOnly &&x = rref();
503   return x; // cxx98_20-error {{cannot bind to lvalue of type}}
504 }
505 
test5()506 void test5() try {
507   CopyOnly x;
508   throw x; // cxx23-error {{no matching constructor for initialization}}
509 } catch (...) {
510 }
511 
512 } // namespace test_simpler_implicit_move
513 
514 namespace test_auto_variables {
515 
516 struct S {};
517 
518 template <class T> struct range {
519   S *begin() const;
520   S *end() const;
521 };
522 
test_dependent_ranged_for()523 template <class T> S test_dependent_ranged_for() {
524   for (auto x : range<T>())
525     return x;
526   return S();
527 }
528 template S test_dependent_ranged_for<int>();
529 
530 template <class T> struct X {};
531 
test_dependent_invalid_decl()532 template <class T> X<T> test_dependent_invalid_decl() {
533   auto x = X<T>().foo(); // expected-error {{no member named 'foo'}}
534   return x;
535 }
536 template X<int> test_dependent_invalid_decl<int>(); // expected-note {{requested here}}
537 
538 } // namespace test_auto_variables
539 
540 namespace PR51708 {
541 
542 class a1;                  // expected-note 4 {{forward declaration of 'PR51708::a1'}}
543 template <class> class A2; // expected-note 4 {{template is declared here}}
544 using a2 = A2<int>;
545 
f()546 template <class b> b f() {
547   // expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
548   // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
549 
550   b d;
551   // expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
552   // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
553 
554   return d;
555 }
556 template a1 f<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
557 template a2 f<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}
558 
g()559 template <class b> b g() {
560   // expected-error@-1 {{incomplete result type 'PR51708::a1' in function definition}}
561   // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
562 
563   b d __attribute__((aligned(1)));
564   // expected-error@-1 {{variable has incomplete type 'PR51708::a1'}}
565   // expected-error@-2 {{implicit instantiation of undefined template 'PR51708::A2<int>}}
566 
567   return d;
568 }
569 template a1 g<a1>(); // expected-note-re {{in instantiation {{.*}} requested here}}
570 template a2 g<a2>(); // expected-note-re {{in instantiation {{.*}} requested here}}
571 
572 } // namespace PR51708
573