diff options
Diffstat (limited to 'test/CXX/special/class.temporary/p6.cpp')
-rw-r--r-- | test/CXX/special/class.temporary/p6.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/test/CXX/special/class.temporary/p6.cpp b/test/CXX/special/class.temporary/p6.cpp new file mode 100644 index 000000000000..077385fb7aaa --- /dev/null +++ b/test/CXX/special/class.temporary/p6.cpp @@ -0,0 +1,240 @@ +// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor' + +namespace std { + typedef decltype(sizeof(int)) size_t; + + template <class E> + struct initializer_list { + const E *begin; + size_t size; + initializer_list() : begin(nullptr), size(0) {} + }; +} + +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<dtor&&>(ctor()); + // CHECK: call {{.*}}then + then(); + // CHECK: call {{.*}}dtor + // CHECK: } +} +// CHECK-LABEL: const_cast +void test_const_cast() { + // CHECK: call {{.*}}ctor + auto &&x = const_cast<dtor&&>(ctor()); + // CHECK: call {{.*}}then + then(); + // CHECK: call {{.*}}dtor + // CHECK: } +} +// CHECK-LABEL: reinterpret_cast +void test_reinterpret_cast() { + // CHECK: call {{.*}}ctor + auto &&x = reinterpret_cast<dtor&&>(static_cast<dtor&&>(ctor())); + // CHECK: call {{.*}}then + then(); + // CHECK: call {{.*}}dtor + // CHECK: } +} +// CHECK-LABEL: dynamic_cast +void test_dynamic_cast() { + // CHECK: call {{.*}}ctor + auto &&x = dynamic_cast<dtor&&>(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: } +} |