destructors.cpp revision 0903421e36c174a82597f83bd296f3cd5b5f169b
1// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | FileCheck %s 2 3// CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev 4// CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev 5// CHECK: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev 6// CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev 7// CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev 8 9// CHECK: @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev 10// CHECK: @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev 11// CHECK: @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev 12 13struct A { 14 int a; 15 16 ~A(); 17}; 18 19// Base with non-trivial destructor 20struct B : A { 21 ~B(); 22}; 23 24B::~B() { } 25 26// Field with non-trivial destructor 27struct C { 28 A a; 29 30 ~C(); 31}; 32 33C::~C() { } 34 35namespace PR7526 { 36 extern void foo(); 37 struct allocator { 38 ~allocator() throw(); 39 }; 40 41 struct allocator_derived : allocator { }; 42 43 // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR5529::A"* %this) unnamed_addr 44 // CHECK: call void @__cxa_call_unexpected 45 allocator::~allocator() throw() { foo(); } 46 47 // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR5529::A"* %this) unnamed_addr 48 // CHECK-NOT: call void @__cxa_call_unexpected 49 // CHECK: } 50 void foo() { 51 allocator_derived ad; 52 } 53} 54 55// PR5084 56template<typename T> 57class A1 { 58 ~A1(); 59}; 60 61template<> A1<char>::~A1(); 62 63// PR5529 64namespace PR5529 { 65 struct A { 66 ~A(); 67 }; 68 69 A::~A() { } 70 struct B : A { 71 virtual ~B(); 72 }; 73 74 B::~B() {} 75} 76 77// FIXME: there's a known problem in the codegen here where, if one 78// destructor throws, the remaining destructors aren't run. Fix it, 79// then make this code check for it. 80namespace test0 { 81 void foo(); 82 struct VBase { ~VBase(); }; 83 struct Base { ~Base(); }; 84 struct Member { ~Member(); }; 85 86 struct A : Base { 87 Member M; 88 ~A(); 89 }; 90 91 // The function-try-block won't suppress -mconstructor-aliases here. 92 A::~A() try { } catch (int i) {} 93 94// complete destructor alias tested above 95 96// CHECK: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr 97// CHECK: invoke void @_ZN5test06MemberD1Ev 98// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]] 99// CHECK: invoke void @_ZN5test04BaseD2Ev 100// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] 101 102 struct B : Base, virtual VBase { 103 Member M; 104 ~B(); 105 }; 106 B::~B() try { } catch (int i) {} 107 // It will suppress the delegation optimization here, though. 108 109// CHECK: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr 110// CHECK: invoke void @_ZN5test06MemberD1Ev 111// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]] 112// CHECK: invoke void @_ZN5test04BaseD2Ev 113// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] 114// CHECK: invoke void @_ZN5test05VBaseD2Ev 115// CHECK: unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]] 116 117// CHECK: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr 118// CHECK: invoke void @_ZN5test06MemberD1Ev 119// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]] 120// CHECK: invoke void @_ZN5test04BaseD2Ev 121// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]] 122} 123 124// Test base-class aliasing. 125namespace test1 { 126 struct A { ~A(); char ***m; }; // non-trivial destructor 127 struct B { ~B(); }; // non-trivial destructor 128 struct Empty { }; // trivial destructor, empty 129 struct NonEmpty { int x; }; // trivial destructor, non-empty 130 131 // There must be a definition in this translation unit for the alias 132 // optimization to apply. 133 A::~A() { delete m; } 134 135 struct M : A { ~M(); }; 136 M::~M() {} // alias tested above 137 138 struct N : A, Empty { ~N(); }; 139 N::~N() {} // alias tested above 140 141 struct O : Empty, A { ~O(); }; 142 O::~O() {} // alias tested above 143 144 struct P : NonEmpty, A { ~P(); }; 145 P::~P() {} // CHECK: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr 146 147 struct Q : A, B { ~Q(); }; 148 Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::M"* %this) unnamed_addr 149 150 struct R : A { ~R(); }; 151 R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::M"* %this) unnamed_addr 152 153 struct S : A { ~S(); int x; }; 154 S::~S() {} // alias tested above 155 156 struct T : A { ~T(); B x; }; 157 T::~T() {} // CHECK: define void @_ZN5test11TD2Ev(%"struct.test1::T"* %this) unnamed_addr 158 159 // The VTT parameter prevents this. We could still make this work 160 // for calling conventions that are safe against extra parameters. 161 struct U : A, virtual B { ~U(); }; 162 U::~U() {} // CHECK: define void @_ZN5test11UD2Ev(%"struct.test1::U"* %this, i8** %vtt) unnamed_addr 163} 164 165// PR6471 166namespace test2 { 167 struct A { ~A(); char ***m; }; 168 struct B : A { ~B(); }; 169 170 B::~B() {} 171 // CHECK: define void @_ZN5test21BD2Ev(%"struct.test1::M"* %this) unnamed_addr 172 // CHECK: call void @_ZN5test21AD2Ev 173} 174 175// PR7142 176namespace test3 { 177 struct A { virtual ~A(); }; 178 struct B { virtual ~B(); }; 179 namespace { // internal linkage => deferred 180 struct C : A, B {}; // ~B() in D requires a this-adjustment thunk 181 struct D : C {}; // D::~D() is an alias to C::~C() 182 } 183 184 void test() { 185 new D; // Force emission of D's vtable 186 } 187 188 // Checked at top of file: 189 // @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev 190 191 // More checks at end of file. 192 193} 194 195namespace test4 { 196 struct A { ~A(); }; 197 198 // CHECK: define void @_ZN5test43fooEv() 199 // CHECK: call void @_ZN5test41AD1Ev 200 // CHECK: ret void 201 void foo() { 202 { 203 A a; 204 goto failure; 205 } 206 207 failure: 208 return; 209 } 210 211 // CHECK: define void @_ZN5test43barEi( 212 // CHECK: [[X:%.*]] = alloca i32 213 // CHECK-NEXT: [[A:%.*]] = alloca 214 // CHECK: br label 215 // CHECK: [[TMP:%.*]] = load i32* [[X]] 216 // CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0 217 // CHECK-NEXT: br i1 218 // CHECK: call void @_ZN5test41AD1Ev( 219 // CHECK: br label 220 // CHECK: [[TMP:%.*]] = load i32* [[X]] 221 // CHECK: [[TMP2:%.*]] = add nsw i32 [[TMP]], -1 222 // CHECK: store i32 [[TMP2]], i32* [[X]] 223 // CHECK: br label 224 // CHECK: ret void 225 void bar(int x) { 226 for (A a; x; ) { 227 x--; 228 } 229 } 230} 231 232// PR7575 233namespace test5 { 234 struct A { ~A(); }; 235 236 // This is really unnecessarily verbose; we should be using phis, 237 // even at -O0. 238 239 // CHECK: define void @_ZN5test53fooEv() 240 // CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align 241 // CHECK-NEXT: [[IVAR:%.*]] = alloca i64 242 // CHECK: [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]] 243 // CHECK-NEXT: store i64 5, i64* [[IVAR]] 244 // CHECK-NEXT: br label 245 // CHECK: [[I:%.*]] = load i64* [[IVAR]] 246 // CHECK-NEXT: icmp ne i64 [[I]], 0 247 // CHECK-NEXT: br i1 248 // CHECK: [[I:%.*]] = load i64* [[IVAR]] 249 // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1 250 // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]] 251 // CHECK-NEXT: call void @_ZN5test51AD1Ev( 252 // CHECK-NEXT: br label 253 // CHECK: [[I:%.*]] = load i64* [[IVAR]] 254 // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1 255 // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]] 256 // CHECK-NEXT: br label 257 // CHECK: ret void 258 void foo() { 259 A elems[5]; 260 } 261} 262 263namespace test6 { 264 void opaque(); 265 266 struct A { ~A(); }; 267 template <unsigned> struct B { B(); ~B(); int _; }; 268 struct C : B<0>, B<1>, virtual B<2>, virtual B<3> { 269 A x, y, z; 270 271 C(); 272 ~C(); 273 }; 274 275 C::C() { opaque(); } 276 // CHECK: define void @_ZN5test61CC1Ev(%"struct.test6::C"* %this) unnamed_addr 277 // CHECK: call void @_ZN5test61BILj2EEC2Ev 278 // CHECK: invoke void @_ZN5test61BILj3EEC2Ev 279 // CHECK: invoke void @_ZN5test61BILj0EEC2Ev 280 // CHECK: invoke void @_ZN5test61BILj1EEC2Ev 281 // CHECK: invoke void @_ZN5test66opaqueEv 282 // CHECK: ret void 283 // FIXME: way too much EH cleanup code follows 284 285 C::~C() { opaque(); } 286 // CHECK: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr 287 // CHECK: invoke void @_ZN5test61CD2Ev 288 // CHECK: invoke void @_ZN5test61BILj3EED2Ev 289 // CHECK: call void @_ZN5test61BILj2EED2Ev 290 // CHECK: ret void 291 // CHECK: invoke void @_ZN5test61BILj3EED2Ev 292 // CHECK: invoke void @_ZN5test61BILj2EED2Ev 293 294 // CHECK: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr 295 // CHECK: invoke void @_ZN5test66opaqueEv 296 // CHECK: invoke void @_ZN5test61AD1Ev 297 // CHECK: invoke void @_ZN5test61AD1Ev 298 // CHECK: invoke void @_ZN5test61AD1Ev 299 // CHECK: invoke void @_ZN5test61BILj1EED2Ev 300 // CHECK: call void @_ZN5test61BILj0EED2Ev 301 // CHECK: ret void 302 // CHECK: invoke void @_ZN5test61AD1Ev 303 // CHECK: invoke void @_ZN5test61AD1Ev 304 // CHECK: invoke void @_ZN5test61AD1Ev 305 // CHECK: invoke void @_ZN5test61BILj1EED2Ev 306 // CHECK: invoke void @_ZN5test61BILj0EED2Ev 307} 308 309// PR 9197 310namespace test7 { 311 struct D { ~D(); }; 312 313 struct A { ~A(); }; 314 A::~A() { } 315 316 struct B : public A { 317 ~B(); 318 D arr[1]; 319 }; 320 321 // Verify that this doesn't get emitted as an alias 322 // CHECK: define void @_ZN5test71BD2Ev( 323 // CHECK: invoke void @_ZN5test71DD1Ev( 324 // CHECK: call void @_ZN5test71AD2Ev( 325 B::~B() {} 326 327} 328 329// Checks from test3: 330 331 // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::<anonymous namespace>::D"* %this) unnamed_addr 332 // CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev( 333 // CHECK: call void @_ZdlPv({{.*}}) nounwind 334 // CHECK: ret void 335 // CHECK: call i8* @llvm.eh.exception( 336 // CHECK: call void @_ZdlPv({{.*}}) nounwind 337 // CHECK: call void @_Unwind_Resume( 338 339 // Checked at top of file: 340 // @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev 341 // @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev 342 343 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev( 344 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 345 // CHECK: call void @_ZN5test312_GLOBAL__N_11DD1Ev( 346 // CHECK: ret void 347 348 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev( 349 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 350 // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev( 351 // CHECK: ret void 352 353 // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr 354 // CHECK: invoke void @_ZN5test31BD2Ev( 355 // CHECK: call void @_ZN5test31AD2Ev( 356 // CHECK: ret void 357 358 // CHECK: declare void @_ZN5test31BD2Ev( 359 // CHECK: declare void @_ZN5test31AD2Ev( 360 361 // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr 362 // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev( 363 // CHECK: call void @_ZdlPv({{.*}}) nounwind 364 // CHECK: ret void 365 // CHECK: call i8* @llvm.eh.exception() 366 // CHECK: call void @_ZdlPv({{.*}}) nounwind 367 // CHECK: call void @_Unwind_Resume( 368 369 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( 370 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 371 // CHECK: call void @_ZN5test312_GLOBAL__N_11CD1Ev( 372 // CHECK: ret void 373 374 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev( 375 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 376 // CHECK: call void @_ZN5test312_GLOBAL__N_11CD0Ev( 377 // CHECK: ret void 378