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.PR7526::allocator"* %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.PR7526::allocator_derived"* %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::Q"* %this) unnamed_addr 149 150 struct R : A { ~R(); }; 151 R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::R"* %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.test2::B"* %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 // CHECK: define void @_ZN5test53fooEv() 237 // CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align 238 // CHECK-NEXT: [[EXN:%.*]] = alloca i8* 239 // CHECK-NEXT: [[SEL:%.*]] = alloca i32 240 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0 241 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 242 // CHECK-NEXT: br label 243 // CHECK: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] 244 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1 245 // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]]) 246 // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]] 247 // CHECK-NEXT: br i1 [[T0]], 248 // CHECK: ret void 249 // lpad 250 // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]] 251 // CHECK-NEXT: br i1 [[EMPTY]] 252 // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] 253 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 254 // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]]) 255 // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] 256 // CHECK-NEXT: br i1 [[DONE]], 257 void foo() { 258 A elems[5]; 259 } 260} 261 262namespace test6 { 263 void opaque(); 264 265 struct A { ~A(); }; 266 template <unsigned> struct B { B(); ~B(); int _; }; 267 struct C : B<0>, B<1>, virtual B<2>, virtual B<3> { 268 A x, y, z; 269 270 C(); 271 ~C(); 272 }; 273 274 C::C() { opaque(); } 275 // CHECK: define void @_ZN5test61CC1Ev(%"struct.test6::C"* %this) unnamed_addr 276 // CHECK: call void @_ZN5test61BILj2EEC2Ev 277 // CHECK: invoke void @_ZN5test61BILj3EEC2Ev 278 // CHECK: invoke void @_ZN5test61BILj0EEC2Ev 279 // CHECK: invoke void @_ZN5test61BILj1EEC2Ev 280 // CHECK: invoke void @_ZN5test66opaqueEv 281 // CHECK: ret void 282 // FIXME: way too much EH cleanup code follows 283 284 C::~C() { opaque(); } 285 // CHECK: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr 286 // CHECK: invoke void @_ZN5test61CD2Ev 287 // CHECK: invoke void @_ZN5test61BILj3EED2Ev 288 // CHECK: call void @_ZN5test61BILj2EED2Ev 289 // CHECK: ret void 290 // CHECK: invoke void @_ZN5test61BILj3EED2Ev 291 // CHECK: invoke void @_ZN5test61BILj2EED2Ev 292 293 // CHECK: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr 294 // CHECK: invoke void @_ZN5test66opaqueEv 295 // CHECK: invoke void @_ZN5test61AD1Ev 296 // CHECK: invoke void @_ZN5test61AD1Ev 297 // CHECK: invoke void @_ZN5test61AD1Ev 298 // CHECK: invoke void @_ZN5test61BILj1EED2Ev 299 // CHECK: call void @_ZN5test61BILj0EED2Ev 300 // CHECK: ret void 301 // CHECK: invoke void @_ZN5test61AD1Ev 302 // CHECK: invoke void @_ZN5test61AD1Ev 303 // CHECK: invoke void @_ZN5test61AD1Ev 304 // CHECK: invoke void @_ZN5test61BILj1EED2Ev 305 // CHECK: invoke void @_ZN5test61BILj0EED2Ev 306} 307 308// PR 9197 309namespace test7 { 310 struct D { ~D(); }; 311 312 struct A { ~A(); }; 313 A::~A() { } 314 315 struct B : public A { 316 ~B(); 317 D arr[1]; 318 }; 319 320 // Verify that this doesn't get emitted as an alias 321 // CHECK: define void @_ZN5test71BD2Ev( 322 // CHECK: invoke void @_ZN5test71DD1Ev( 323 // CHECK: call void @_ZN5test71AD2Ev( 324 B::~B() {} 325} 326 327// PR10467 328namespace test8 { 329 struct A { A(); ~A(); }; 330 331 void die() __attribute__((noreturn)); 332 void test() { 333 A x; 334 while (1) { 335 A y; 336 goto l; 337 } 338 l: die(); 339 } 340 341 // CHECK: define void @_ZN5test84testEv() 342 // CHECK: [[X:%.*]] = alloca [[A:%.*]], align 1 343 // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]], align 1 344 // CHECK: call void @_ZN5test81AC1Ev([[A]]* [[X]]) 345 // CHECK-NEXT: br label 346 // CHECK: invoke void @_ZN5test81AC1Ev([[A]]* [[Y]]) 347 // CHECK: invoke void @_ZN5test81AD1Ev([[A]]* [[Y]]) 348 // CHECK-NOT: switch 349 // CHECK: invoke void @_ZN5test83dieEv() 350 // CHECK: unreachable 351} 352 353// Checks from test3: 354 355 // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::<anonymous namespace>::D"* %this) unnamed_addr 356 // CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev( 357 // CHECK: call void @_ZdlPv({{.*}}) nounwind 358 // CHECK: ret void 359 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 360 // CHECK-NEXT: cleanup 361 // CHECK: call void @_ZdlPv({{.*}}) nounwind 362 // CHECK: resume { i8*, i32 } 363 364 // Checked at top of file: 365 // @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev 366 // @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev 367 368 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev( 369 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 370 // CHECK: call void @_ZN5test312_GLOBAL__N_11DD1Ev( 371 // CHECK: ret void 372 373 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev( 374 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 375 // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev( 376 // CHECK: ret void 377 378 // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr 379 // CHECK: invoke void @_ZN5test31BD2Ev( 380 // CHECK: call void @_ZN5test31AD2Ev( 381 // CHECK: ret void 382 383 // CHECK: declare void @_ZN5test31BD2Ev( 384 // CHECK: declare void @_ZN5test31AD2Ev( 385 386 // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr 387 // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev( 388 // CHECK: call void @_ZdlPv({{.*}}) nounwind 389 // CHECK: ret void 390 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) 391 // CHECK-NEXT: cleanup 392 // CHECK: call void @_ZdlPv({{.*}}) nounwind 393 // CHECK: resume { i8*, i32 } 394 395 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( 396 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 397 // CHECK: call void @_ZN5test312_GLOBAL__N_11CD1Ev( 398 // CHECK: ret void 399 400 // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev( 401 // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 402 // CHECK: call void @_ZN5test312_GLOBAL__N_11CD0Ev( 403 // CHECK: ret void 404