704 lines · cpp
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-LABEL3 4namespace std {5 typedef decltype(sizeof(int)) size_t;6 7 template <class E>8 struct initializer_list {9 const E *begin;10 size_t size;11 initializer_list() : begin(nullptr), size(0) {}12 };13 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;22 };23 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;33 };34 35 template <typename T>36 struct lock_guard {37 lock_guard(T) {}38 ~lock_guard() {}39 };40 41 struct mutex {};42} // namespace std43 44void then();45 46struct dtor {47 ~dtor();48};49 50dtor ctor();51 52auto &&lambda = [a = {ctor()}] {};53// CHECK-LABEL: define54// CHECK: call {{.*}}ctor55// CHECK: call {{.*}}atexit{{.*}}global_array_dtor56 57// CHECK-LABEL: define{{.*}}global_array_dtor58// CHECK: call {{.*}}dtor59 60// [lifetime extension occurs if the object was obtained by]61// -- a temporary materialization conversion62// CHECK-LABEL: ref_binding63void ref_binding() {64 // CHECK: call {{.*}}ctor65 auto &&x = ctor();66 // CHECK: call {{.*}}then67 then();68 // CHECK: call {{.*}}dtor69 // CHECK: }70}71 72// -- ( expression )73// CHECK-LABEL: parens74void parens() {75 // CHECK: call {{.*}}ctor76 auto &&x = ctor();77 // CHECK: call {{.*}}then78 then();79 // CHECK: call {{.*}}dtor80 // CHECK: }81}82 83// -- subscripting of an array84// CHECK-LABEL: array_subscript_185void array_subscript_1() {86 using T = dtor[1];87 // CHECK: call {{.*}}ctor88 auto &&x = T{ctor()}[0];89 // CHECK: call {{.*}}then90 then();91 // CHECK: call {{.*}}dtor92 // CHECK: }93}94// CHECK-LABEL: array_subscript_295void array_subscript_2() {96 using T = dtor[1];97 // CHECK: call {{.*}}ctor98 auto &&x = ((dtor*)T{ctor()})[0];99 // CHECK: call {{.*}}dtor100 // CHECK: call {{.*}}then101 then();102 // CHECK: }103}104 105struct with_member { dtor d; ~with_member(); };106struct with_ref_member { dtor &&d; ~with_ref_member(); };107 108// -- a class member access using the . operator [...]109// CHECK-LABEL: member_access_1110void member_access_1() {111 // CHECK: call {{.*}}ctor112 auto &&x = with_member{ctor()}.d;113 // CHECK: call {{.*}}then114 then();115 // CHECK: call {{.*}}with_member116 // CHECK: }117}118// CHECK-LABEL: member_access_2119void member_access_2() {120 // CHECK: call {{.*}}ctor121 auto &&x = with_ref_member{ctor()}.d;122 // CHECK: call {{.*}}with_ref_member123 // CHECK: call {{.*}}dtor124 // CHECK: call {{.*}}then125 then();126 // CHECK: }127}128// CHECK-LABEL: member_access_3129void member_access_3() {130 // CHECK: call {{.*}}ctor131 auto &&x = (&(const with_member&)with_member{ctor()})->d;132 // CHECK: call {{.*}}with_member133 // CHECK: call {{.*}}then134 then();135 // CHECK: }136}137 138// -- a pointer-to-member operation using the .* operator [...]139// CHECK-LABEL: member_ptr_access_1140void member_ptr_access_1() {141 // CHECK: call {{.*}}ctor142 auto &&x = with_member{ctor()}.*&with_member::d;143 // CHECK: call {{.*}}then144 then();145 // CHECK: call {{.*}}with_member146 // CHECK: }147}148// CHECK-LABEL: member_ptr_access_2149void member_ptr_access_2() {150 // CHECK: call {{.*}}ctor151 auto &&x = (&(const with_member&)with_member{ctor()})->*&with_member::d;152 // CHECK: call {{.*}}with_member153 // CHECK: call {{.*}}then154 then();155 // CHECK: }156}157 158// -- a [named] cast [...]159// CHECK-LABEL: static_cast160void test_static_cast() {161 // CHECK: call {{.*}}ctor162 auto &&x = static_cast<dtor&&>(ctor());163 // CHECK: call {{.*}}then164 then();165 // CHECK: call {{.*}}dtor166 // CHECK: }167}168// CHECK-LABEL: const_cast169void test_const_cast() {170 // CHECK: call {{.*}}ctor171 auto &&x = const_cast<dtor&&>(ctor());172 // CHECK: call {{.*}}then173 then();174 // CHECK: call {{.*}}dtor175 // CHECK: }176}177// CHECK-LABEL: reinterpret_cast178void test_reinterpret_cast() {179 // CHECK: call {{.*}}ctor180 auto &&x = reinterpret_cast<dtor&&>(static_cast<dtor&&>(ctor()));181 // CHECK: call {{.*}}then182 then();183 // CHECK: call {{.*}}dtor184 // CHECK: }185}186// CHECK-LABEL: dynamic_cast187void test_dynamic_cast() {188 // CHECK: call {{.*}}ctor189 auto &&x = dynamic_cast<dtor&&>(ctor());190 // CHECK: call {{.*}}then191 then();192 // CHECK: call {{.*}}dtor193 // CHECK: }194}195 196// -- [explicit cast notation is defined in terms of the above]197// CHECK-LABEL: c_style_cast198void c_style_cast() {199 // CHECK: call {{.*}}ctor200 auto &&x = (dtor&&)ctor();201 // CHECK: call {{.*}}then202 then();203 // CHECK: call {{.*}}dtor204 // CHECK: }205}206// CHECK-LABEL: function_style_cast207void function_style_cast() {208 // CHECK: call {{.*}}ctor209 using R = dtor&&;210 auto &&x = R(ctor());211 // CHECK: call {{.*}}then212 then();213 // CHECK: call {{.*}}dtor214 // CHECK: }215}216 217// -- a conditional operator218// CHECK-LABEL: conditional219void conditional(bool b) {220 // CHECK: call {{.*}}ctor221 // CHECK: call {{.*}}ctor222 auto &&x = b ? (dtor&&)ctor() : (dtor&&)ctor();223 // CHECK: call {{.*}}then224 then();225 // CHECK: call {{.*}}dtor226 // CHECK: call {{.*}}dtor227 // CHECK: }228}229 230// -- a comma expression231// CHECK-LABEL: comma232void comma() {233 // CHECK: call {{.*}}ctor234 auto &&x = (true, (dtor&&)ctor());235 // CHECK: call {{.*}}then236 then();237 // CHECK: call {{.*}}dtor238 // CHECK: }239}240 241 242// This applies recursively: if an object is lifetime-extended and contains a243// reference, the referent is also extended.244// CHECK-LABEL: init_capture_ref245void init_capture_ref() {246 // CHECK: call {{.*}}ctor247 auto x = [&a = (const dtor&)ctor()] {};248 // CHECK: call {{.*}}then249 then();250 // CHECK: call {{.*}}dtor251 // CHECK: }252}253// CHECK-LABEL: init_capture_ref_indirect254void init_capture_ref_indirect() {255 // CHECK: call {{.*}}ctor256 auto x = [&a = (const dtor&)ctor()] {};257 // CHECK: call {{.*}}then258 then();259 // CHECK: call {{.*}}dtor260 // CHECK: }261}262// CHECK-LABEL: init_capture_init_list263void init_capture_init_list() {264 // CHECK: call {{.*}}ctor265 auto x = [a = {ctor()}] {};266 // CHECK: call {{.*}}then267 then();268 // CHECK: call {{.*}}dtor269 // CHECK: }270}271 272void check_dr1815() { // dr1815: yes273#if __cplusplus >= 201402L274 275 struct A {276 int &&r = 0;277 ~A() {}278 };279 280 struct B {281 A &&a = A{};282 ~B() {}283 };284 B a = {};285 286 // CHECK: call {{.*}}block_scope_begin_function287 extern void block_scope_begin_function();288 extern void block_scope_end_function();289 block_scope_begin_function();290 {291 // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev292 // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev293 B b = {};294 }295 // CHECK: call {{.*}}block_scope_end_function296 block_scope_end_function();297 298 // CHECK: call {{.*}}some_other_function299 extern void some_other_function();300 some_other_function();301 // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev302 // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev303#endif304}305 306namespace P2718R0 {307namespace basic {308template <typename E> using T2 = std::list<E>;309template <typename E> const T2<E> &f1_temp(const T2<E> &t) { return t; }310template <typename E> const T2<E> &f2_temp(T2<E> t) { return t; }311template <typename E> T2<E> g_temp() { return T2<E>{}; }312 313template <typename E>314void 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() extended319}320 321template <typename E>322void 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 behavior331}332 333template void foo_dependent_context1<int>();334template void foo_dependent_context2<int>();335} // namespace basic336 337namespace discard_value_expression {338template <typename T>339void 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++ 2023346 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks347}348 349template <typename T>350void 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++ 2023357 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks358}359 360template <typename T>361void 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++ 2023368 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks369}370 371template void f_dependent_context1<int>();372template void f_dependent_context2<int>();373template void f_dependent_context3<int>();374} // namespace discard_value_expression375 376namespace member_call {377template <typename T>378struct 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(); }386};387 388template <typename E>389ListWrapper<E> g_temp() { return ListWrapper<E>{}; }390 391template <typename T>392void 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()) {}400}401 402template void member_call_dependent_context<int>();403} // namespace member_call404 405namespace default_arg {406template <typename T>407struct DefaultArg {408 DefaultArg() {}409 DefaultArg(int) {}410 ~DefaultArg() {}411};412 413template <typename T>414struct C2 : public std::list<T> {415 C2() {}416 C2(int, const C2 &, const DefaultArg<T> &Default = DefaultArg<T>{}) {}417};418 419template <typename T>420std::list<T> temp_foo(const std::list<T>&, const DefaultArg<T> &Default = DefaultArg<T>{}) {421 return std::list<T>{};422}423 424template <typename T>425void 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>{})) {}432}433 434template <typename T>435void 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>{}))) {}444}445 446template <typename T>447void 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(457 458 for (auto e : C2<T>(0, C2<T>(0, C2<T>(0, C2<T>())))) {}459}460 461template void default_arg_dependent_context1<int>();462template void default_arg_dependent_context2<int>();463template void default_arg_dependent_context3<int>();464} // namespace default_arg465 466namespace default_init {467template <class T>468struct DepA {469 T arr[1];470 ~DepA() {}471};472 473template <class T>474struct 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]; }480};481 482template <typename T>483void 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}) {}489}490 491template <typename T>492void 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) {}498}499 500template void default_init1_dependent<DepB<int>>();501template void default_init2_dependent<DepB<int>>();502} // namespace default_init503 504// -- Examples from https://wg21.link/p2718r0505extern void block_scope_begin_function();506extern void block_scope_end_function();507namespace std_examples {508using T = std::list<int>;509const T& f1(const T& t) { return t; }510const T& f2(T t) { return t; }511T g();512void foo() {513 // CHECK-CXX23: define {{.*}} void @_ZN7P2718R012std_examples3fooEv()514 // CHECK-CXX23: call void @_ZN7P2718R026block_scope_begin_functionEv515 block_scope_begin_function();516 {517 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012std_examples1gEv518 // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R012std_examples2f1ERKSt4listIiE519 // CHECK-CXX23: for.cond.cleanup:520 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev521 for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended522 }523 // CHECK-CXX23: call void @_ZN7P2718R024block_scope_end_functionEv524 block_scope_end_function();525 526 // The lifetime of temporary returned by g() in this case will not be extended.527 // CHECK-CXX23: call void @_ZN7P2718R026block_scope_begin_functionEv528 block_scope_begin_function();529 {530 // CHECK-CXX23-NEXT: call void @_ZN7P2718R012std_examples1gEv531 // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R012std_examples2f2ESt4listIiE532 // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev533 for (auto e : f2(g())) {} // undefined behavior534 }535 // CHECK-CXX23: call void @_ZN7P2718R024block_scope_end_functionEv536 block_scope_end_function();537}538} // namespace std_examples539 540namespace basic {541using T = std::list<int>;542const T& f1(const T& t) { return t; }543const T& f2(T t) { return t; }544T g() { return T{}; }545 546void 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() extended551}552 553void 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 behavior559}560} // namespace basic561 562namespace discard_value_expression {563void 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++ 2023570 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks571}572 573void 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++ 2023580 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks581}582 583void 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++ 2023590 std::lock_guard<std::mutex> guard(m); // OK in C++ 2023, now deadlocks591}592} // namespace discard_value_expression593 594namespace member_call {595using A = ListWrapper<int>;596 597A g() { return A(); }598const A &f1(const A &t) { return t; }599 600void 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()) {}608}609} // namespace member_call610 611namespace default_arg {612using A = std::list<int>;613using DefaultA = DefaultArg<int>;614struct C : public A {615 C() {}616 C(int, const C &, const DefaultA & = DefaultA()) {}617};618 619A foo(const A&, const DefaultA &Default = DefaultA()) {620 return A();621}622 623int (&some_func(const A & = A{}))[3];624 625void 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()) {}630}631 632void 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())))) {}641}642 643void 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())))) {}654}655} // namespace default_arg656 657namespace default_init {658struct X {659 int x;660 ~X() {}661};662 663struct Y {664 int y;665 const X &x = X{1};666 ~Y() {}667};668 669struct A {670 int arr[1];671 const Y &y = Y{1};672 ~A() {}673};674 675struct 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]; }681};682 683void 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}) {}691}692 693void 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) {}701}702} // namespace default_init703} // namespace P2718R0704