[NFC][AArch64] Explicitly define undefined bits for instructions (#122129)
[llvm-project.git] / clang / test / CXX / special / class.temporary / p6.cpp
blob2b1b531b7172ca3d535823ba96619e0fe762edaf
1 // RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor'
2 // RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK-CXX23,CHECK-CXX23-NEXT,CHECK-CXX23-LABEL
4 namespace std {
5 typedef decltype(sizeof(int)) size_t;
7 template <class E>
8 struct initializer_list {
9 const E *begin;
10 size_t size;
11 initializer_list() : begin(nullptr), size(0) {}
14 template <typename E>
15 struct list {
16 list() {}
17 ~list() {}
18 E *begin();
19 E *end();
20 const E *begin() const;
21 const E *end() const;
24 template <typename E>
25 struct vector {
26 vector() {}
27 vector(std::initializer_list<E>) {}
28 ~vector() {}
29 E *begin();
30 E *end();
31 const E *begin() const;
32 const E *end() const;
35 template <typename T>
36 struct lock_guard {
37 lock_guard(T) {}
38 ~lock_guard() {}
41 struct mutex {};
42 } // namespace std
44 void then();
46 struct dtor {
47 ~dtor();
50 dtor ctor();
52 auto &&lambda = [a = {ctor()}] {};
53 // CHECK-LABEL: define
54 // CHECK: call {{.*}}ctor
55 // CHECK: call {{.*}}atexit{{.*}}global_array_dtor
57 // CHECK-LABEL: define{{.*}}global_array_dtor
58 // CHECK: call {{.*}}dtor
60 // [lifetime extension occurs if the object was obtained by]
61 // -- a temporary materialization conversion
62 // CHECK-LABEL: ref_binding
63 void ref_binding() {
64 // CHECK: call {{.*}}ctor
65 auto &&x = ctor();
66 // CHECK: call {{.*}}then
67 then();
68 // CHECK: call {{.*}}dtor
69 // CHECK: }
72 // -- ( expression )
73 // CHECK-LABEL: parens
74 void parens() {
75 // CHECK: call {{.*}}ctor
76 auto &&x = ctor();
77 // CHECK: call {{.*}}then
78 then();
79 // CHECK: call {{.*}}dtor
80 // CHECK: }
83 // -- subscripting of an array
84 // CHECK-LABEL: array_subscript_1
85 void array_subscript_1() {
86 using T = dtor[1];
87 // CHECK: call {{.*}}ctor
88 auto &&x = T{ctor()}[0];
89 // CHECK: call {{.*}}then
90 then();
91 // CHECK: call {{.*}}dtor
92 // CHECK: }
94 // CHECK-LABEL: array_subscript_2
95 void array_subscript_2() {
96 using T = dtor[1];
97 // CHECK: call {{.*}}ctor
98 auto &&x = ((dtor*)T{ctor()})[0];
99 // CHECK: call {{.*}}dtor
100 // CHECK: call {{.*}}then
101 then();
102 // CHECK: }
105 struct with_member { dtor d; ~with_member(); };
106 struct with_ref_member { dtor &&d; ~with_ref_member(); };
108 // -- a class member access using the . operator [...]
109 // CHECK-LABEL: member_access_1
110 void member_access_1() {
111 // CHECK: call {{.*}}ctor
112 auto &&x = with_member{ctor()}.d;
113 // CHECK: call {{.*}}then
114 then();
115 // CHECK: call {{.*}}with_member
116 // CHECK: }
118 // CHECK-LABEL: member_access_2
119 void member_access_2() {
120 // CHECK: call {{.*}}ctor
121 auto &&x = with_ref_member{ctor()}.d;
122 // CHECK: call {{.*}}with_ref_member
123 // CHECK: call {{.*}}dtor
124 // CHECK: call {{.*}}then
125 then();
126 // CHECK: }
128 // CHECK-LABEL: member_access_3
129 void member_access_3() {
130 // CHECK: call {{.*}}ctor
131 auto &&x = (&(const with_member&)with_member{ctor()})->d;
132 // CHECK: call {{.*}}with_member
133 // CHECK: call {{.*}}then
134 then();
135 // CHECK: }
138 // -- a pointer-to-member operation using the .* operator [...]
139 // CHECK-LABEL: member_ptr_access_1
140 void member_ptr_access_1() {
141 // CHECK: call {{.*}}ctor
142 auto &&x = with_member{ctor()}.*&with_member::d;
143 // CHECK: call {{.*}}then
144 then();
145 // CHECK: call {{.*}}with_member
146 // CHECK: }
148 // CHECK-LABEL: member_ptr_access_2
149 void member_ptr_access_2() {
150 // CHECK: call {{.*}}ctor
151 auto &&x = (&(const with_member&)with_member{ctor()})->*&with_member::d;
152 // CHECK: call {{.*}}with_member
153 // CHECK: call {{.*}}then
154 then();
155 // CHECK: }
158 // -- a [named] cast [...]
159 // CHECK-LABEL: static_cast
160 void test_static_cast() {
161 // CHECK: call {{.*}}ctor
162 auto &&x = static_cast<dtor&&>(ctor());
163 // CHECK: call {{.*}}then
164 then();
165 // CHECK: call {{.*}}dtor
166 // CHECK: }
168 // CHECK-LABEL: const_cast
169 void test_const_cast() {
170 // CHECK: call {{.*}}ctor
171 auto &&x = const_cast<dtor&&>(ctor());
172 // CHECK: call {{.*}}then
173 then();
174 // CHECK: call {{.*}}dtor
175 // CHECK: }
177 // CHECK-LABEL: reinterpret_cast
178 void test_reinterpret_cast() {
179 // CHECK: call {{.*}}ctor
180 auto &&x = reinterpret_cast<dtor&&>(static_cast<dtor&&>(ctor()));
181 // CHECK: call {{.*}}then
182 then();
183 // CHECK: call {{.*}}dtor
184 // CHECK: }
186 // CHECK-LABEL: dynamic_cast
187 void test_dynamic_cast() {
188 // CHECK: call {{.*}}ctor
189 auto &&x = dynamic_cast<dtor&&>(ctor());
190 // CHECK: call {{.*}}then
191 then();
192 // CHECK: call {{.*}}dtor
193 // CHECK: }
196 // -- [explicit cast notation is defined in terms of the above]
197 // CHECK-LABEL: c_style_cast
198 void c_style_cast() {
199 // CHECK: call {{.*}}ctor
200 auto &&x = (dtor&&)ctor();
201 // CHECK: call {{.*}}then
202 then();
203 // CHECK: call {{.*}}dtor
204 // CHECK: }
206 // CHECK-LABEL: function_style_cast
207 void function_style_cast() {
208 // CHECK: call {{.*}}ctor
209 using R = dtor&&;
210 auto &&x = R(ctor());
211 // CHECK: call {{.*}}then
212 then();
213 // CHECK: call {{.*}}dtor
214 // CHECK: }
217 // -- a conditional operator
218 // CHECK-LABEL: conditional
219 void conditional(bool b) {
220 // CHECK: call {{.*}}ctor
221 // CHECK: call {{.*}}ctor
222 auto &&x = b ? (dtor&&)ctor() : (dtor&&)ctor();
223 // CHECK: call {{.*}}then
224 then();
225 // CHECK: call {{.*}}dtor
226 // CHECK: call {{.*}}dtor
227 // CHECK: }
230 // -- a comma expression
231 // CHECK-LABEL: comma
232 void comma() {
233 // CHECK: call {{.*}}ctor
234 auto &&x = (true, (dtor&&)ctor());
235 // CHECK: call {{.*}}then
236 then();
237 // CHECK: call {{.*}}dtor
238 // CHECK: }
242 // This applies recursively: if an object is lifetime-extended and contains a
243 // reference, the referent is also extended.
244 // CHECK-LABEL: init_capture_ref
245 void init_capture_ref() {
246 // CHECK: call {{.*}}ctor
247 auto x = [&a = (const dtor&)ctor()] {};
248 // CHECK: call {{.*}}then
249 then();
250 // CHECK: call {{.*}}dtor
251 // CHECK: }
253 // CHECK-LABEL: init_capture_ref_indirect
254 void init_capture_ref_indirect() {
255 // CHECK: call {{.*}}ctor
256 auto x = [&a = (const dtor&)ctor()] {};
257 // CHECK: call {{.*}}then
258 then();
259 // CHECK: call {{.*}}dtor
260 // CHECK: }
262 // CHECK-LABEL: init_capture_init_list
263 void init_capture_init_list() {
264 // CHECK: call {{.*}}ctor
265 auto x = [a = {ctor()}] {};
266 // CHECK: call {{.*}}then
267 then();
268 // CHECK: call {{.*}}dtor
269 // CHECK: }
272 void check_dr1815() { // dr1815: yes
273 #if __cplusplus >= 201402L
275 struct A {
276 int &&r = 0;
277 ~A() {}
280 struct B {
281 A &&a = A{};
282 ~B() {}
284 B a = {};
286 // CHECK: call {{.*}}block_scope_begin_function
287 extern void block_scope_begin_function();
288 extern void block_scope_end_function();
289 block_scope_begin_function();
291 // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev
292 // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev
293 B b = {};
295 // CHECK: call {{.*}}block_scope_end_function
296 block_scope_end_function();
298 // CHECK: call {{.*}}some_other_function
299 extern void some_other_function();
300 some_other_function();
301 // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev
302 // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev
303 #endif
306 namespace P2718R0 {
307 namespace basic {
308 template <typename E> using T2 = std::list<E>;
309 template <typename E> const T2<E> &f1_temp(const T2<E> &t) { return t; }
310 template <typename E> const T2<E> &f2_temp(T2<E> t) { return t; }
311 template <typename E> T2<E> g_temp() { return T2<E>{}; }
313 template <typename E>
314 void foo_dependent_context1() {
315 // CHECK-CXX23: void @_ZN7P2718R05basic22foo_dependent_context1IiEEvv()
316 // CHECK-CXX23: for.cond.cleanup:
317 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
318 for (auto e : f1_temp(g_temp<E>())) {} // OK, lifetime of return value of g() extended
321 template <typename E>
322 void foo_dependent_context2() {
323 // CHECK-CXX23: void @_ZN7P2718R05basic22foo_dependent_context2IiEEvv()
324 // CHECK-CXX23-NEXT: entry:
325 // CHECK-CXX23-NEXT: call void @_ZN7P2718R05basic6g_tempIiEESt4listIT_Ev(
326 // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R05basic7f2_tempIiEERKSt4listIT_ES4_(
327 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
328 // CHECK-CXX23: call {{.*}} @_ZNKSt4listIiE5beginEv(
329 // CHECK-CXX23: call {{.*}} @_ZNKSt4listIiE3endEv(
330 for (auto e : f2_temp(g_temp<E>())) {} // undefined behavior
333 template void foo_dependent_context1<int>();
334 template void foo_dependent_context2<int>();
335 } // namespace basic
337 namespace discard_value_expression {
338 template <typename T>
339 void f_dependent_context1() {
340 std::vector<T> v = { 42, 17, 13 };
341 std::mutex m;
342 // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression20f_dependent_context1IiEEvv()
343 // CHECK-CXX23-LABEL: for.cond.cleanup:
344 // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev(
345 for (T x : std::lock_guard<std::mutex>(m), v) // lock released in C++ 2023
346 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks
349 template <typename T>
350 void f_dependent_context2() {
351 std::vector<T> v = { 42, 17, 13 };
352 std::mutex m;
353 // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression20f_dependent_context2IiEEvv()
354 // CHECK-CXX23-LABEL: for.cond.cleanup:
355 // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev(
356 for (T x : (void)std::lock_guard<std::mutex>(m), v) // lock released in C++ 2023
357 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks
360 template <typename T>
361 void f_dependent_context3() {
362 std::vector<T> v = { 42, 17, 13 };
363 std::mutex m;
364 // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression20f_dependent_context3IiEEvv()
365 // CHECK-CXX23-LABEL: for.cond.cleanup:
366 // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev(
367 for (T x : static_cast<void>(std::lock_guard<std::mutex>(m)), v) // lock released in C++ 2023
368 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks
371 template void f_dependent_context1<int>();
372 template void f_dependent_context2<int>();
373 template void f_dependent_context3<int>();
374 } // namespace discard_value_expression
376 namespace member_call {
377 template <typename T>
378 struct ListWrapper {
379 std::list<T> list;
380 ListWrapper() {}
381 ~ListWrapper() {}
382 const T *begin() const { return list.begin(); }
383 const T *end() const { return list.end(); }
384 ListWrapper& r() { return *this; }
385 ListWrapper g() { return ListWrapper(); }
388 template <typename E>
389 ListWrapper<E> g_temp() { return ListWrapper<E>{}; }
391 template <typename T>
392 void member_call_dependent_context() {
393 // CHECK-CXX23: void @_ZN7P2718R011member_call29member_call_dependent_contextIiEEvv()
394 // CHECK-CXX23-LABEL: for.cond.cleanup:
395 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
396 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
397 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
398 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
399 for (auto e : g_temp<T>().r().g().r().g().r().g()) {}
402 template void member_call_dependent_context<int>();
403 } // namespace member_call
405 namespace default_arg {
406 template <typename T>
407 struct DefaultArg {
408 DefaultArg() {}
409 DefaultArg(int) {}
410 ~DefaultArg() {}
413 template <typename T>
414 struct C2 : public std::list<T> {
415 C2() {}
416 C2(int, const C2 &, const DefaultArg<T> &Default = DefaultArg<T>{}) {}
419 template <typename T>
420 std::list<T> temp_foo(const std::list<T>&, const DefaultArg<T> &Default = DefaultArg<T>{}) {
421 return std::list<T>{};
424 template <typename T>
425 void default_arg_dependent_context1() {
426 // CHECK-CXX23: void @_ZN7P2718R011default_arg30default_arg_dependent_context1IiEEvv()
427 // CHECK-CXX23-LABEL: for.cond.cleanup:
428 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
429 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
430 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
431 for (auto e : temp_foo(std::list<T>{})) {}
434 template <typename T>
435 void default_arg_dependent_context2() {
436 // CHECK-CXX23: void @_ZN7P2718R011default_arg30default_arg_dependent_context2IiEEvv()
437 // CHECK-CXX23-LABEL: for.cond.cleanup:
438 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
439 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
440 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
441 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
442 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
443 for (auto e : temp_foo(temp_foo(std::list<T>{}))) {}
446 template <typename T>
447 void default_arg_dependent_context3() {
448 // CHECK-CXX23: void @_ZN7P2718R011default_arg30default_arg_dependent_context3IiEEvv()
449 // CHECK-CXX23-LABEL: for.cond.cleanup:
450 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev(
451 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
452 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev(
453 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
454 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev(
455 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
456 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev(
458 for (auto e : C2<T>(0, C2<T>(0, C2<T>(0, C2<T>())))) {}
461 template void default_arg_dependent_context1<int>();
462 template void default_arg_dependent_context2<int>();
463 template void default_arg_dependent_context3<int>();
464 } // namespace default_arg
466 namespace default_init {
467 template <class T>
468 struct DepA {
469 T arr[1];
470 ~DepA() {}
473 template <class T>
474 struct DepB {
475 int x;
476 const DepA<T> &a = DepA<T>{{0}};
477 ~DepB() {}
478 const int *begin() { return a.arr; }
479 const int *end() { return &a.arr[1]; }
482 template <typename T>
483 void default_init1_dependent() {
484 // CHECK-CXX23: void @_ZN7P2718R012default_init23default_init1_dependentINS0_4DepBIiEEEEvv()
485 // CHECK-CXX23-LABEL: for.cond.cleanup:
486 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepBIiED1Ev(
487 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepAIiED1Ev(
488 for (auto &&x : T{0}) {}
491 template <typename T>
492 void default_init2_dependent() {
493 // CHECK-CXX23: void @_ZN7P2718R012default_init23default_init2_dependentINS0_4DepBIiEEEEvv()
494 // CHECK-CXX23-LABEL: for.cond.cleanup:
495 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepBIiED1Ev(
496 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepAIiED1Ev(
497 for (auto &&x : T{0}.a.arr) {}
500 template void default_init1_dependent<DepB<int>>();
501 template void default_init2_dependent<DepB<int>>();
502 } // namespace default_init
504 // -- Examples from https://wg21.link/p2718r0
505 extern void block_scope_begin_function();
506 extern void block_scope_end_function();
507 namespace std_examples {
508 using T = std::list<int>;
509 const T& f1(const T& t) { return t; }
510 const T& f2(T t) { return t; }
511 T g();
512 void foo() {
513 // CHECK-CXX23: define {{.*}} void @_ZN7P2718R012std_examples3fooEv()
514 // CHECK-CXX23: call void @_ZN7P2718R026block_scope_begin_functionEv
515 block_scope_begin_function();
517 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012std_examples1gEv
518 // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R012std_examples2f1ERKSt4listIiE
519 // CHECK-CXX23: for.cond.cleanup:
520 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev
521 for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended
523 // CHECK-CXX23: call void @_ZN7P2718R024block_scope_end_functionEv
524 block_scope_end_function();
526 // The lifetime of temporary returned by g() in this case will not be extended.
527 // CHECK-CXX23: call void @_ZN7P2718R026block_scope_begin_functionEv
528 block_scope_begin_function();
530 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012std_examples1gEv
531 // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R012std_examples2f2ESt4listIiE
532 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev
533 for (auto e : f2(g())) {} // undefined behavior
535 // CHECK-CXX23: call void @_ZN7P2718R024block_scope_end_functionEv
536 block_scope_end_function();
538 } // namespace std_examples
540 namespace basic {
541 using T = std::list<int>;
542 const T& f1(const T& t) { return t; }
543 const T& f2(T t) { return t; }
544 T g() { return T{}; }
546 void foo1() {
547 // CHECK-CXX23: void @_ZN7P2718R05basic4foo1Ev()
548 // CHECK-CXX23: for.cond.cleanup:
549 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
550 for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended
553 void foo2() {
554 // CHECK-CXX23: void @_ZN7P2718R05basic4foo2Ev()
555 // CHECK-CXX23-NEXT: call void @_ZN7P2718R05basic1gEv(
556 // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R05basic2f2ESt4listIiE(
557 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
558 for (auto e : f2(g())) {} // undefined behavior
560 } // namespace basic
562 namespace discard_value_expression {
563 void f1() {
564 std::vector<int> v = { 42, 17, 13 };
565 std::mutex m;
566 // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression2f1Ev()
567 // CHECK-CXX23-LABEL: for.cond.cleanup:
568 // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev(
569 for (int x : std::lock_guard<std::mutex>(m), v) // lock released in C++ 2023
570 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks
573 void f2() {
574 std::vector<int> v = { 42, 17, 13 };
575 std::mutex m;
576 // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression2f2Ev()
577 // CHECK-CXX23-LABEL: for.cond.cleanup:
578 // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev(
579 for (int x : (void)std::lock_guard<std::mutex>(m), v) // lock released in C++ 2023
580 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks
583 void f3() {
584 std::vector<int> v = { 42, 17, 13 };
585 std::mutex m;
586 // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression2f3Ev()
587 // CHECK-CXX23-LABEL: for.cond.cleanup:
588 // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev(
589 for (int x : static_cast<void>(std::lock_guard<std::mutex>(m)), v) // lock released in C++ 2023
590 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks
592 } // namespace discard_value_expression
594 namespace member_call {
595 using A = ListWrapper<int>;
597 A g() { return A(); }
598 const A &f1(const A &t) { return t; }
600 void member_call() {
601 // CHECK-CXX23: void @_ZN7P2718R011member_call11member_callEv()
602 // CHECK-CXX23-LABEL: for.cond.cleanup:
603 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
604 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
605 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
606 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
607 for (auto e : g().r().g().r().g().r().g()) {}
609 } // namespace member_call
611 namespace default_arg {
612 using A = std::list<int>;
613 using DefaultA = DefaultArg<int>;
614 struct C : public A {
615 C() {}
616 C(int, const C &, const DefaultA & = DefaultA()) {}
619 A foo(const A&, const DefaultA &Default = DefaultA()) {
620 return A();
623 int (&some_func(const A & = A{}))[3];
625 void default_arg1() {
626 // CHECK-CXX23: void @_ZN7P2718R011default_arg12default_arg1Ev()
627 // CHECK-CXX23-LABEL: for.cond.cleanup:
628 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
629 for (auto e : some_func()) {}
632 void default_arg2() {
633 // CHECK-CXX23: void @_ZN7P2718R011default_arg12default_arg2Ev()
634 // CHECK-CXX23-LABEL: for.cond.cleanup:
635 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
636 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
637 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
638 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
639 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev(
640 for (auto e : some_func(foo(foo(A())))) {}
643 void default_arg3() {
644 // CHECK-CXX23: void @_ZN7P2718R011default_arg12default_arg3Ev()
645 // CHECK-CXX23-LABEL: for.cond.cleanup:
646 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev(
647 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
648 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev(
649 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
650 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev(
651 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev(
652 // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev(
653 for (auto e : C(0, C(0, C(0, C())))) {}
655 } // namespace default_arg
657 namespace default_init {
658 struct X {
659 int x;
660 ~X() {}
663 struct Y {
664 int y;
665 const X &x = X{1};
666 ~Y() {}
669 struct A {
670 int arr[1];
671 const Y &y = Y{1};
672 ~A() {}
675 struct B {
676 int x;
677 const A &a = A{{0}};
678 ~B() {}
679 const int *begin() { return a.arr; }
680 const int *end() { return &a.arr[1]; }
683 void default_init1() {
684 // CHECK-CXX23: void @_ZN7P2718R012default_init13default_init1Ev()
685 // CHECK-CXX23-LABEL: for.cond.cleanup:
686 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1BD1Ev(
687 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1AD1Ev(
688 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1YD1Ev(
689 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1XD1Ev(
690 for (auto &&x : B{0}) {}
693 void default_init2() {
694 // CHECK-CXX23: void @_ZN7P2718R012default_init13default_init2Ev()
695 // CHECK-CXX23-LABEL: for.cond.cleanup:
696 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1BD1Ev(
697 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1AD1Ev(
698 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1YD1Ev(
699 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1XD1Ev(
700 for (auto &&x : B{0}.a.arr) {}
702 } // namespace default_init
703 } // namespace P2718R0