// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor' // 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 namespace std { typedef decltype(sizeof(int)) size_t; template struct initializer_list { const E *begin; size_t size; initializer_list() : begin(nullptr), size(0) {} }; template struct list { list() {} ~list() {} E *begin(); E *end(); const E *begin() const; const E *end() const; }; template struct vector { vector() {} vector(std::initializer_list) {} ~vector() {} E *begin(); E *end(); const E *begin() const; const E *end() const; }; template struct lock_guard { lock_guard(T) {} ~lock_guard() {} }; struct mutex {}; } // namespace std void then(); struct dtor { ~dtor(); }; dtor ctor(); auto &&lambda = [a = {ctor()}] {}; // CHECK-LABEL: define // CHECK: call {{.*}}ctor // CHECK: call {{.*}}atexit{{.*}}global_array_dtor // CHECK-LABEL: define{{.*}}global_array_dtor // CHECK: call {{.*}}dtor // [lifetime extension occurs if the object was obtained by] // -- a temporary materialization conversion // CHECK-LABEL: ref_binding void ref_binding() { // CHECK: call {{.*}}ctor auto &&x = ctor(); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // -- ( expression ) // CHECK-LABEL: parens void parens() { // CHECK: call {{.*}}ctor auto &&x = ctor(); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // -- subscripting of an array // CHECK-LABEL: array_subscript_1 void array_subscript_1() { using T = dtor[1]; // CHECK: call {{.*}}ctor auto &&x = T{ctor()}[0]; // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: array_subscript_2 void array_subscript_2() { using T = dtor[1]; // CHECK: call {{.*}}ctor auto &&x = ((dtor*)T{ctor()})[0]; // CHECK: call {{.*}}dtor // CHECK: call {{.*}}then then(); // CHECK: } } struct with_member { dtor d; ~with_member(); }; struct with_ref_member { dtor &&d; ~with_ref_member(); }; // -- a class member access using the . operator [...] // CHECK-LABEL: member_access_1 void member_access_1() { // CHECK: call {{.*}}ctor auto &&x = with_member{ctor()}.d; // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}with_member // CHECK: } } // CHECK-LABEL: member_access_2 void member_access_2() { // CHECK: call {{.*}}ctor auto &&x = with_ref_member{ctor()}.d; // CHECK: call {{.*}}with_ref_member // CHECK: call {{.*}}dtor // CHECK: call {{.*}}then then(); // CHECK: } } // CHECK-LABEL: member_access_3 void member_access_3() { // CHECK: call {{.*}}ctor auto &&x = (&(const with_member&)with_member{ctor()})->d; // CHECK: call {{.*}}with_member // CHECK: call {{.*}}then then(); // CHECK: } } // -- a pointer-to-member operation using the .* operator [...] // CHECK-LABEL: member_ptr_access_1 void member_ptr_access_1() { // CHECK: call {{.*}}ctor auto &&x = with_member{ctor()}.*&with_member::d; // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}with_member // CHECK: } } // CHECK-LABEL: member_ptr_access_2 void member_ptr_access_2() { // CHECK: call {{.*}}ctor auto &&x = (&(const with_member&)with_member{ctor()})->*&with_member::d; // CHECK: call {{.*}}with_member // CHECK: call {{.*}}then then(); // CHECK: } } // -- a [named] cast [...] // CHECK-LABEL: static_cast void test_static_cast() { // CHECK: call {{.*}}ctor auto &&x = static_cast(ctor()); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: const_cast void test_const_cast() { // CHECK: call {{.*}}ctor auto &&x = const_cast(ctor()); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: reinterpret_cast void test_reinterpret_cast() { // CHECK: call {{.*}}ctor auto &&x = reinterpret_cast(static_cast(ctor())); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: dynamic_cast void test_dynamic_cast() { // CHECK: call {{.*}}ctor auto &&x = dynamic_cast(ctor()); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // -- [explicit cast notation is defined in terms of the above] // CHECK-LABEL: c_style_cast void c_style_cast() { // CHECK: call {{.*}}ctor auto &&x = (dtor&&)ctor(); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: function_style_cast void function_style_cast() { // CHECK: call {{.*}}ctor using R = dtor&&; auto &&x = R(ctor()); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // -- a conditional operator // CHECK-LABEL: conditional void conditional(bool b) { // CHECK: call {{.*}}ctor // CHECK: call {{.*}}ctor auto &&x = b ? (dtor&&)ctor() : (dtor&&)ctor(); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: call {{.*}}dtor // CHECK: } } // -- a comma expression // CHECK-LABEL: comma void comma() { // CHECK: call {{.*}}ctor auto &&x = (true, (dtor&&)ctor()); // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // This applies recursively: if an object is lifetime-extended and contains a // reference, the referent is also extended. // CHECK-LABEL: init_capture_ref void init_capture_ref() { // CHECK: call {{.*}}ctor auto x = [&a = (const dtor&)ctor()] {}; // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: init_capture_ref_indirect void init_capture_ref_indirect() { // CHECK: call {{.*}}ctor auto x = [&a = (const dtor&)ctor()] {}; // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } // CHECK-LABEL: init_capture_init_list void init_capture_init_list() { // CHECK: call {{.*}}ctor auto x = [a = {ctor()}] {}; // CHECK: call {{.*}}then then(); // CHECK: call {{.*}}dtor // CHECK: } } void check_dr1815() { // dr1815: yes #if __cplusplus >= 201402L struct A { int &&r = 0; ~A() {} }; struct B { A &&a = A{}; ~B() {} }; B a = {}; // CHECK: call {{.*}}block_scope_begin_function extern void block_scope_begin_function(); extern void block_scope_end_function(); block_scope_begin_function(); { // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev B b = {}; } // CHECK: call {{.*}}block_scope_end_function block_scope_end_function(); // CHECK: call {{.*}}some_other_function extern void some_other_function(); some_other_function(); // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev #endif } namespace P2718R0 { namespace basic { template using T2 = std::list; template const T2 &f1_temp(const T2 &t) { return t; } template const T2 &f2_temp(T2 t) { return t; } template T2 g_temp() { return T2{}; } template void foo_dependent_context1() { // CHECK-CXX23: void @_ZN7P2718R05basic22foo_dependent_context1IiEEvv() // CHECK-CXX23: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : f1_temp(g_temp())) {} // OK, lifetime of return value of g() extended } template void foo_dependent_context2() { // CHECK-CXX23: void @_ZN7P2718R05basic22foo_dependent_context2IiEEvv() // CHECK-CXX23-NEXT: entry: // CHECK-CXX23-NEXT: call void @_ZN7P2718R05basic6g_tempIiEESt4listIT_Ev( // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R05basic7f2_tempIiEERKSt4listIT_ES4_( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( // CHECK-CXX23: call {{.*}} @_ZNKSt4listIiE5beginEv( // CHECK-CXX23: call {{.*}} @_ZNKSt4listIiE3endEv( for (auto e : f2_temp(g_temp())) {} // undefined behavior } template void foo_dependent_context1(); template void foo_dependent_context2(); } // namespace basic namespace discard_value_expression { template void f_dependent_context1() { std::vector v = { 42, 17, 13 }; std::mutex m; // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression20f_dependent_context1IiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev( for (T x : std::lock_guard(m), v) // lock released in C++ 2023 std::lock_guard guard(m); // OK in C++ 2023, now deadlocks } template void f_dependent_context2() { std::vector v = { 42, 17, 13 }; std::mutex m; // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression20f_dependent_context2IiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev( for (T x : (void)std::lock_guard(m), v) // lock released in C++ 2023 std::lock_guard guard(m); // OK in C++ 2023, now deadlocks } template void f_dependent_context3() { std::vector v = { 42, 17, 13 }; std::mutex m; // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression20f_dependent_context3IiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev( for (T x : static_cast(std::lock_guard(m)), v) // lock released in C++ 2023 std::lock_guard guard(m); // OK in C++ 2023, now deadlocks } template void f_dependent_context1(); template void f_dependent_context2(); template void f_dependent_context3(); } // namespace discard_value_expression namespace member_call { template struct ListWrapper { std::list list; ListWrapper() {} ~ListWrapper() {} const T *begin() const { return list.begin(); } const T *end() const { return list.end(); } ListWrapper& r() { return *this; } ListWrapper g() { return ListWrapper(); } }; template ListWrapper g_temp() { return ListWrapper{}; } template void member_call_dependent_context() { // CHECK-CXX23: void @_ZN7P2718R011member_call29member_call_dependent_contextIiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( for (auto e : g_temp().r().g().r().g().r().g()) {} } template void member_call_dependent_context(); } // namespace member_call namespace default_arg { template struct DefaultArg { DefaultArg() {} DefaultArg(int) {} ~DefaultArg() {} }; template struct C2 : public std::list { C2() {} C2(int, const C2 &, const DefaultArg &Default = DefaultArg{}) {} }; template std::list temp_foo(const std::list&, const DefaultArg &Default = DefaultArg{}) { return std::list{}; } template void default_arg_dependent_context1() { // CHECK-CXX23: void @_ZN7P2718R011default_arg30default_arg_dependent_context1IiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : temp_foo(std::list{})) {} } template void default_arg_dependent_context2() { // CHECK-CXX23: void @_ZN7P2718R011default_arg30default_arg_dependent_context2IiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : temp_foo(temp_foo(std::list{}))) {} } template void default_arg_dependent_context3() { // CHECK-CXX23: void @_ZN7P2718R011default_arg30default_arg_dependent_context3IiEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg2C2IiED1Ev( for (auto e : C2(0, C2(0, C2(0, C2())))) {} } template void default_arg_dependent_context1(); template void default_arg_dependent_context2(); template void default_arg_dependent_context3(); } // namespace default_arg namespace default_init { template struct DepA { T arr[1]; ~DepA() {} }; template struct DepB { int x; const DepA &a = DepA{{0}}; ~DepB() {} const int *begin() { return a.arr; } const int *end() { return &a.arr[1]; } }; template void default_init1_dependent() { // CHECK-CXX23: void @_ZN7P2718R012default_init23default_init1_dependentINS0_4DepBIiEEEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepBIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepAIiED1Ev( for (auto &&x : T{0}) {} } template void default_init2_dependent() { // CHECK-CXX23: void @_ZN7P2718R012default_init23default_init2_dependentINS0_4DepBIiEEEEvv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepBIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepAIiED1Ev( for (auto &&x : T{0}.a.arr) {} } template void default_init1_dependent>(); template void default_init2_dependent>(); } // namespace default_init // -- Examples from https://wg21.link/p2718r0 extern void block_scope_begin_function(); extern void block_scope_end_function(); namespace std_examples { using T = std::list; const T& f1(const T& t) { return t; } const T& f2(T t) { return t; } T g(); void foo() { // CHECK-CXX23: define {{.*}} void @_ZN7P2718R012std_examples3fooEv() // CHECK-CXX23: call void @_ZN7P2718R026block_scope_begin_functionEv block_scope_begin_function(); { // CHECK-CXX23-NEXT: call void @_ZN7P2718R012std_examples1gEv // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R012std_examples2f1ERKSt4listIiE // CHECK-CXX23: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended } // CHECK-CXX23: call void @_ZN7P2718R024block_scope_end_functionEv block_scope_end_function(); // The lifetime of temporary returned by g() in this case will not be extended. // CHECK-CXX23: call void @_ZN7P2718R026block_scope_begin_functionEv block_scope_begin_function(); { // CHECK-CXX23-NEXT: call void @_ZN7P2718R012std_examples1gEv // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R012std_examples2f2ESt4listIiE // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev for (auto e : f2(g())) {} // undefined behavior } // CHECK-CXX23: call void @_ZN7P2718R024block_scope_end_functionEv block_scope_end_function(); } } // namespace std_examples namespace basic { using T = std::list; const T& f1(const T& t) { return t; } const T& f2(T t) { return t; } T g() { return T{}; } void foo1() { // CHECK-CXX23: void @_ZN7P2718R05basic4foo1Ev() // CHECK-CXX23: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended } void foo2() { // CHECK-CXX23: void @_ZN7P2718R05basic4foo2Ev() // CHECK-CXX23-NEXT: call void @_ZN7P2718R05basic1gEv( // CHECK-CXX23-NEXT: call {{.*}} @_ZN7P2718R05basic2f2ESt4listIiE( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : f2(g())) {} // undefined behavior } } // namespace basic namespace discard_value_expression { void f1() { std::vector v = { 42, 17, 13 }; std::mutex m; // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression2f1Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev( for (int x : std::lock_guard(m), v) // lock released in C++ 2023 std::lock_guard guard(m); // OK in C++ 2023, now deadlocks } void f2() { std::vector v = { 42, 17, 13 }; std::mutex m; // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression2f2Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev( for (int x : (void)std::lock_guard(m), v) // lock released in C++ 2023 std::lock_guard guard(m); // OK in C++ 2023, now deadlocks } void f3() { std::vector v = { 42, 17, 13 }; std::mutex m; // CHECK-CXX23: void @_ZN7P2718R024discard_value_expression2f3Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt10lock_guardISt5mutexED1Ev( for (int x : static_cast(std::lock_guard(m)), v) // lock released in C++ 2023 std::lock_guard guard(m); // OK in C++ 2023, now deadlocks } } // namespace discard_value_expression namespace member_call { using A = ListWrapper; A g() { return A(); } const A &f1(const A &t) { return t; } void member_call() { // CHECK-CXX23: void @_ZN7P2718R011member_call11member_callEv() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev( for (auto e : g().r().g().r().g().r().g()) {} } } // namespace member_call namespace default_arg { using A = std::list; using DefaultA = DefaultArg; struct C : public A { C() {} C(int, const C &, const DefaultA & = DefaultA()) {} }; A foo(const A&, const DefaultA &Default = DefaultA()) { return A(); } int (&some_func(const A & = A{}))[3]; void default_arg1() { // CHECK-CXX23: void @_ZN7P2718R011default_arg12default_arg1Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : some_func()) {} } void default_arg2() { // CHECK-CXX23: void @_ZN7P2718R011default_arg12default_arg2Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZNSt4listIiED1Ev( for (auto e : some_func(foo(foo(A())))) {} } void default_arg3() { // CHECK-CXX23: void @_ZN7P2718R011default_arg12default_arg3Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg10DefaultArgIiED1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R011default_arg1CD1Ev( for (auto e : C(0, C(0, C(0, C())))) {} } } // namespace default_arg namespace default_init { struct X { int x; ~X() {} }; struct Y { int y; const X &x = X{1}; ~Y() {} }; struct A { int arr[1]; const Y &y = Y{1}; ~A() {} }; struct B { int x; const A &a = A{{0}}; ~B() {} const int *begin() { return a.arr; } const int *end() { return &a.arr[1]; } }; void default_init1() { // CHECK-CXX23: void @_ZN7P2718R012default_init13default_init1Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1BD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1AD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1YD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1XD1Ev( for (auto &&x : B{0}) {} } void default_init2() { // CHECK-CXX23: void @_ZN7P2718R012default_init13default_init2Ev() // CHECK-CXX23-LABEL: for.cond.cleanup: // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1BD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1AD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1YD1Ev( // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1XD1Ev( for (auto &&x : B{0}.a.arr) {} } } // namespace default_init } // namespace P2718R0