1 // RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor' 2 3 namespace std { 4 typedef decltype(sizeof(int)) size_t; 5 6 template <class E> 7 struct initializer_list { 8 const E *begin; 9 size_t size; initializer_liststd::initializer_list10 initializer_list() : begin(nullptr), size(0) {} 11 }; 12 } 13 14 void then(); 15 16 struct dtor { 17 ~dtor(); 18 }; 19 20 dtor ctor(); 21 __anonbb00a32c0102null22auto &&lambda = [a = {ctor()}] {}; 23 // CHECK-LABEL: define 24 // CHECK: call {{.*}}ctor 25 // CHECK: call {{.*}}atexit{{.*}}global_array_dtor 26 27 // CHECK-LABEL: define{{.*}}global_array_dtor 28 // CHECK: call {{.*}}dtor 29 30 // [lifetime extension occurs if the object was obtained by] 31 // -- a temporary materialization conversion 32 // CHECK-LABEL: ref_binding ref_binding()33void ref_binding() { 34 // CHECK: call {{.*}}ctor 35 auto &&x = ctor(); 36 // CHECK: call {{.*}}then 37 then(); 38 // CHECK: call {{.*}}dtor 39 // CHECK: } 40 } 41 42 // -- ( expression ) 43 // CHECK-LABEL: parens parens()44void parens() { 45 // CHECK: call {{.*}}ctor 46 auto &&x = ctor(); 47 // CHECK: call {{.*}}then 48 then(); 49 // CHECK: call {{.*}}dtor 50 // CHECK: } 51 } 52 53 // -- subscripting of an array 54 // CHECK-LABEL: array_subscript_1 array_subscript_1()55void array_subscript_1() { 56 using T = dtor[1]; 57 // CHECK: call {{.*}}ctor 58 auto &&x = T{ctor()}[0]; 59 // CHECK: call {{.*}}then 60 then(); 61 // CHECK: call {{.*}}dtor 62 // CHECK: } 63 } 64 // CHECK-LABEL: array_subscript_2 array_subscript_2()65void array_subscript_2() { 66 using T = dtor[1]; 67 // CHECK: call {{.*}}ctor 68 auto &&x = ((dtor*)T{ctor()})[0]; 69 // CHECK: call {{.*}}dtor 70 // CHECK: call {{.*}}then 71 then(); 72 // CHECK: } 73 } 74 75 struct with_member { dtor d; ~with_member(); }; 76 struct with_ref_member { dtor &&d; ~with_ref_member(); }; 77 78 // -- a class member access using the . operator [...] 79 // CHECK-LABEL: member_access_1 member_access_1()80void member_access_1() { 81 // CHECK: call {{.*}}ctor 82 auto &&x = with_member{ctor()}.d; 83 // CHECK: call {{.*}}then 84 then(); 85 // CHECK: call {{.*}}with_member 86 // CHECK: } 87 } 88 // CHECK-LABEL: member_access_2 member_access_2()89void member_access_2() { 90 // CHECK: call {{.*}}ctor 91 auto &&x = with_ref_member{ctor()}.d; 92 // CHECK: call {{.*}}with_ref_member 93 // CHECK: call {{.*}}dtor 94 // CHECK: call {{.*}}then 95 then(); 96 // CHECK: } 97 } 98 // CHECK-LABEL: member_access_3 member_access_3()99void member_access_3() { 100 // CHECK: call {{.*}}ctor 101 auto &&x = (&(const with_member&)with_member{ctor()})->d; 102 // CHECK: call {{.*}}with_member 103 // CHECK: call {{.*}}then 104 then(); 105 // CHECK: } 106 } 107 108 // -- a pointer-to-member operation using the .* operator [...] 109 // CHECK-LABEL: member_ptr_access_1 member_ptr_access_1()110void member_ptr_access_1() { 111 // CHECK: call {{.*}}ctor 112 auto &&x = with_member{ctor()}.*&with_member::d; 113 // CHECK: call {{.*}}then 114 then(); 115 // CHECK: call {{.*}}with_member 116 // CHECK: } 117 } 118 // CHECK-LABEL: member_ptr_access_2 member_ptr_access_2()119void member_ptr_access_2() { 120 // CHECK: call {{.*}}ctor 121 auto &&x = (&(const with_member&)with_member{ctor()})->*&with_member::d; 122 // CHECK: call {{.*}}with_member 123 // CHECK: call {{.*}}then 124 then(); 125 // CHECK: } 126 } 127 128 // -- a [named] cast [...] 129 // CHECK-LABEL: static_cast test_static_cast()130void test_static_cast() { 131 // CHECK: call {{.*}}ctor 132 auto &&x = static_cast<dtor&&>(ctor()); 133 // CHECK: call {{.*}}then 134 then(); 135 // CHECK: call {{.*}}dtor 136 // CHECK: } 137 } 138 // CHECK-LABEL: const_cast test_const_cast()139void test_const_cast() { 140 // CHECK: call {{.*}}ctor 141 auto &&x = const_cast<dtor&&>(ctor()); 142 // CHECK: call {{.*}}then 143 then(); 144 // CHECK: call {{.*}}dtor 145 // CHECK: } 146 } 147 // CHECK-LABEL: reinterpret_cast test_reinterpret_cast()148void test_reinterpret_cast() { 149 // CHECK: call {{.*}}ctor 150 auto &&x = reinterpret_cast<dtor&&>(static_cast<dtor&&>(ctor())); 151 // CHECK: call {{.*}}then 152 then(); 153 // CHECK: call {{.*}}dtor 154 // CHECK: } 155 } 156 // CHECK-LABEL: dynamic_cast test_dynamic_cast()157void test_dynamic_cast() { 158 // CHECK: call {{.*}}ctor 159 auto &&x = dynamic_cast<dtor&&>(ctor()); 160 // CHECK: call {{.*}}then 161 then(); 162 // CHECK: call {{.*}}dtor 163 // CHECK: } 164 } 165 166 // -- [explicit cast notation is defined in terms of the above] 167 // CHECK-LABEL: c_style_cast c_style_cast()168void c_style_cast() { 169 // CHECK: call {{.*}}ctor 170 auto &&x = (dtor&&)ctor(); 171 // CHECK: call {{.*}}then 172 then(); 173 // CHECK: call {{.*}}dtor 174 // CHECK: } 175 } 176 // CHECK-LABEL: function_style_cast function_style_cast()177void function_style_cast() { 178 // CHECK: call {{.*}}ctor 179 using R = dtor&&; 180 auto &&x = R(ctor()); 181 // CHECK: call {{.*}}then 182 then(); 183 // CHECK: call {{.*}}dtor 184 // CHECK: } 185 } 186 187 // -- a conditional operator 188 // CHECK-LABEL: conditional conditional(bool b)189void conditional(bool b) { 190 // CHECK: call {{.*}}ctor 191 // CHECK: call {{.*}}ctor 192 auto &&x = b ? (dtor&&)ctor() : (dtor&&)ctor(); 193 // CHECK: call {{.*}}then 194 then(); 195 // CHECK: call {{.*}}dtor 196 // CHECK: call {{.*}}dtor 197 // CHECK: } 198 } 199 200 // -- a comma expression 201 // CHECK-LABEL: comma comma()202void comma() { 203 // CHECK: call {{.*}}ctor 204 auto &&x = (true, (dtor&&)ctor()); 205 // CHECK: call {{.*}}then 206 then(); 207 // CHECK: call {{.*}}dtor 208 // CHECK: } 209 } 210 211 212 // This applies recursively: if an object is lifetime-extended and contains a 213 // reference, the referent is also extended. 214 // CHECK-LABEL: init_capture_ref init_capture_ref()215void init_capture_ref() { 216 // CHECK: call {{.*}}ctor 217 auto x = [&a = (const dtor&)ctor()] {}; 218 // CHECK: call {{.*}}then 219 then(); 220 // CHECK: call {{.*}}dtor 221 // CHECK: } 222 } 223 // CHECK-LABEL: init_capture_ref_indirect init_capture_ref_indirect()224void init_capture_ref_indirect() { 225 // CHECK: call {{.*}}ctor 226 auto x = [&a = (const dtor&)ctor()] {}; 227 // CHECK: call {{.*}}then 228 then(); 229 // CHECK: call {{.*}}dtor 230 // CHECK: } 231 } 232 // CHECK-LABEL: init_capture_init_list init_capture_init_list()233void init_capture_init_list() { 234 // CHECK: call {{.*}}ctor 235 auto x = [a = {ctor()}] {}; 236 // CHECK: call {{.*}}then 237 then(); 238 // CHECK: call {{.*}}dtor 239 // CHECK: } 240 } 241