924 lines · cpp
1// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX112// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++17 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX173// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK,NULL-VALID,CHECK-CXX114 5namespace PR16263 {6 const unsigned int n = 1234;7 extern const int &r = (const int&)n;8 // CHECK: @_ZGRN7PR162631rE_ = internal constant i32 1234,9 // CHECK: @_ZN7PR162631rE ={{.*}} constant ptr @_ZGRN7PR162631rE_,10 11 extern const int &s = reinterpret_cast<const int&>(n);12 // CHECK: @_ZN7PR16263L1nE = internal constant i32 1234, align 413 // CHECK: @_ZN7PR162631sE ={{.*}} constant ptr @_ZN7PR16263L1nE, align 814 15 struct A { int n; };16 struct B { int n; };17 struct C : A, B {};18 extern const A &&a = (A&&)(A&&)(C&&)(C{});19 // CHECK: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer,20 // CHECK: @_ZN7PR162631aE ={{.*}} constant {{.*}} @_ZGRN7PR162631aE_21 22 extern const int &&t = ((B&&)C{}).n;23 // CHECK: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer,24 // CHECK: @_ZN7PR162631tE ={{.*}} constant ptr {{.*}} @_ZGRN7PR162631tE_, {{.*}} 425 26 struct D { double d; C c; };27 extern const int &&u = (123, static_cast<B&&>(0, ((D&&)D{}).*&D::c).n);28 // CHECK: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer29 // CHECK: @_ZN7PR162631uE ={{.*}} constant ptr {{.*}} @_ZGRN7PR162631uE_, {{.*}} 1230}31 32namespace PR20227 {33 struct A { ~A(); };34 struct B { virtual ~B(); };35 struct C : B {};36 37 A &&a = dynamic_cast<A&&>(A{});38 // CHECK: @_ZGRN7PR202271aE_ = internal global39 40 B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{}));41 // CHECK: @_ZGRN7PR202271bE_ = internal global42 43 B &&c = static_cast<C&&>(static_cast<B&&>(C{}));44 // CHECK: @_ZGRN7PR202271cE_ = internal global45}46 47namespace BraceInit {48 typedef const int &CIR;49 CIR x = CIR{3};50 // CHECK-CXX11: @_ZGRN9BraceInit1xE_ = internal constant i32 351 // FIXME: This should still be emitted as 'constant' in C++17.52 // CHECK-CXX17: @_ZGRN9BraceInit1xE_ = internal global i32 353 // CHECK: @_ZN9BraceInit1xE ={{.*}} constant ptr @_ZGRN9BraceInit1xE_54}55 56namespace RefTempSubobject {57 struct SelfReferential {58 int *p = ints;59 int ints[3] = {1, 2, 3};60 };61 62 // CHECK: @_ZGRN16RefTempSubobject2srE_ = internal global { ptr, [3 x i32] } { {{.*}} getelementptr {{.*}} @_ZGRN16RefTempSubobject2srE_, {{.*}}, [3 x i32] [i32 1, i32 2, i32 3] }63 // CHECK: @_ZN16RefTempSubobject2srE = constant {{.*}} @_ZGRN16RefTempSubobject2srE_64 constexpr const SelfReferential &sr = SelfReferential();65}66 67namespace Vector {68 typedef __attribute__((vector_size(16))) int vi4a;69 typedef __attribute__((ext_vector_type(4))) int vi4b;70 struct S {71 vi4a v;72 vi4b w;73 };74 75 int &&r = S().v[1];76 // CHECK: @_ZGRN6Vector1rE_ = internal global i32 0, align 477 // CHECK: @_ZN6Vector1rE = constant ptr @_ZGRN6Vector1rE_, align 878 79 int &&s = S().w[1];80 // CHECK: @_ZGRN6Vector1sE_ = internal global i32 0, align 481 // CHECK: @_ZN6Vector1sE = constant ptr @_ZGRN6Vector1sE_, align 882 83 int &&t = S().w.y;84 // CHECK: @_ZGRN6Vector1tE_ = internal global i32 0, align 485 // CHECK: @_ZN6Vector1tE = constant ptr @_ZGRN6Vector1tE_, align 886}87struct A {88 A();89 ~A();90 void f();91};92 93void f1() {94 // CHECK: call void @_ZN1AC1Ev95 // CHECK: call void @_ZN1AD1Ev96 (void)A();97 98 // CHECK: call void @_ZN1AC1Ev99 // CHECK: call void @_ZN1AD1Ev100 A().f();101}102 103// Function calls104struct B {105 B();106 ~B();107};108 109B g();110 111void f2() {112 // CHECK-NOT: call void @_ZN1BC1Ev113 // CHECK: call void @_ZN1BD1Ev114 (void)g();115}116 117// Member function calls118struct C {119 C();120 ~C();121 122 C f();123};124 125void f3() {126 // CHECK: call void @_ZN1CC1Ev127 // CHECK: call void @_ZN1CD1Ev128 // CHECK: call void @_ZN1CD1Ev129 C().f();130}131 132// Function call operator133struct D {134 D();135 ~D();136 137 D operator()();138};139 140void f4() {141 // CHECK: call void @_ZN1DC1Ev142 // CHECK: call void @_ZN1DD1Ev143 // CHECK: call void @_ZN1DD1Ev144 D()();145}146 147// Overloaded operators148struct E {149 E();150 ~E();151 E operator+(const E&);152 E operator!();153};154 155void f5() {156 // CHECK: call void @_ZN1EC1Ev157 // CHECK: call void @_ZN1EC1Ev158 // CHECK: call void @_ZN1ED1Ev159 // CHECK: call void @_ZN1ED1Ev160 // CHECK: call void @_ZN1ED1Ev161 E() + E();162 163 // CHECK: call void @_ZN1EC1Ev164 // CHECK: call void @_ZN1ED1Ev165 // CHECK: call void @_ZN1ED1Ev166 !E();167}168 169struct F {170 F();171 ~F();172 F& f();173};174 175void f6() {176 // CHECK: call void @_ZN1FC1Ev177 // CHECK: call void @_ZN1FD1Ev178 F().f();179}180 181struct G {182 G();183 G(A);184 ~G();185 operator A();186};187 188void a(const A&);189 190void f7() {191 // CHECK: call void @_ZN1AC1Ev192 // CHECK: call void @_Z1aRK1A193 // CHECK: call void @_ZN1AD1Ev194 a(A());195 196 // CHECK: call void @_ZN1GC1Ev197 // CHECK: call void @_ZN1Gcv1AEv198 // CHECK: call void @_Z1aRK1A199 // CHECK: call void @_ZN1AD1Ev200 // CHECK: call void @_ZN1GD1Ev201 a(G());202}203 204namespace PR5077 {205 206struct A {207 A();208 ~A();209 int f();210};211 212void f();213int g(const A&);214 215struct B {216 int a1;217 int a2;218 B();219 ~B();220};221 222B::B()223 // CHECK: call void @_ZN6PR50771AC1Ev224 // CHECK: call noundef i32 @_ZN6PR50771A1fEv225 // CHECK: call void @_ZN6PR50771AD1Ev226 : a1(A().f())227 // CHECK: call void @_ZN6PR50771AC1Ev228 // CHECK: call noundef i32 @_ZN6PR50771gERKNS_1AE229 // CHECK: call void @_ZN6PR50771AD1Ev230 , a2(g(A()))231{232 // CHECK: call void @_ZN6PR50771fEv233 f();234}235 236}237 238A f8() {239 // CHECK: call void @_ZN1AC1Ev240 // CHECK-NOT: call void @_ZN1AD1Ev241 return A();242 // CHECK: ret void243}244 245struct H {246 H();247 ~H();248 H(const H&);249};250 251void f9(H h) {252 // CHECK: call void @_ZN1HC1Ev253 // CHECK: call void @_Z2f91H254 // CHECK: call void @_ZN1HD1Ev255 f9(H());256 257 // CHECK: call void @_ZN1HC1ERKS_258 // CHECK: call void @_Z2f91H259 // CHECK: call void @_ZN1HD1Ev260 f9(h);261}262 263void f10(const H&);264 265void f11(H h) {266 // CHECK: call void @_ZN1HC1Ev267 // CHECK: call void @_Z3f10RK1H268 // CHECK: call void @_ZN1HD1Ev269 f10(H());270 271 // CHECK: call void @_Z3f10RK1H272 // CHECK-NOT: call void @_ZN1HD1Ev273 // CHECK: ret void274 f10(h);275}276 277// PR5808278struct I {279 I(const char *);280 ~I();281};282 283// CHECK: _Z3f12v284I f12() {285 // CHECK: call void @_ZN1IC1EPKc286 // CHECK-NOT: call void @_ZN1ID1Ev287 // CHECK: ret void288 return "Hello";289}290 291// PR5867292namespace PR5867 {293 struct S {294 S();295 S(const S &);296 ~S();297 };298 299 void f(S, int);300 // CHECK-LABEL: define{{.*}} void @_ZN6PR58671gEv301 void g() {302 // CHECK: call void @_ZN6PR58671SC1Ev303 // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi304 // CHECK-NEXT: call void @_ZN6PR58671SD1Ev305 // CHECK-NEXT: ret void306 (f)(S(), 0);307 }308 309 // CHECK-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_310 template<typename T>311 void g2(T) {312 // CHECK: call void @_ZN6PR58671SC1Ev313 // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi314 // CHECK-NEXT: call void @_ZN6PR58671SD1Ev315 // CHECK-NEXT: ret void316 (f)(S(), 0);317 }318 319 void h() {320 g2(17);321 }322}323 324// PR6199325namespace PR6199 {326 struct A { ~A(); };327 328 struct B { operator A(); };329 330 // CHECK-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_331 template<typename T> A f2(T) {332 B b;333 // CHECK: call void @_ZN6PR61991BcvNS_1AEEv334 // CHECK-NEXT: ret void335 return b;336 }337 338 template A f2<int>(int);339 340}341 342namespace T12 {343 344struct A {345 A();346 ~A();347 int f();348};349 350int& f(int);351 352// CHECK-LABEL: define{{.*}} void @_ZN3T121gEv353void g() {354 // CHECK: call void @_ZN3T121AC1Ev355 // CHECK-NEXT: call noundef i32 @_ZN3T121A1fEv(356 // CHECK-NEXT: call noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN3T121fEi(357 // CHECK-NEXT: call void @_ZN3T121AD1Ev(358 int& i = f(A().f());359}360 361}362 363namespace PR6648 {364 struct B {365 ~B();366 };367 B foo;368 struct D;369 D& zed(B);370 void foobar() {371 // NULL-INVALID: call noundef nonnull align 1 ptr @_ZN6PR66483zedENS_1BE372 // NULL-VALID: call noundef align 1 ptr @_ZN6PR66483zedENS_1BE373 zed(foo);374 }375}376 377namespace UserConvertToValue {378 struct X {379 X(int);380 X(const X&);381 ~X();382 };383 384 void f(X);385 386 // CHECK: void @_ZN18UserConvertToValue1gEv()387 void g() {388 // CHECK: call void @_ZN18UserConvertToValue1XC1Ei389 // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE390 // CHECK: call void @_ZN18UserConvertToValue1XD1Ev391 // CHECK: ret void392 f(1);393 }394}395 396namespace PR7556 {397 struct A { ~A(); };398 struct B { int i; ~B(); };399 struct C { int C::*pm; ~C(); };400 // CHECK-LABEL: define{{.*}} void @_ZN6PR75563fooEv()401 void foo() {402 // CHECK: call void @_ZN6PR75561AD1Ev403 A();404 // CHECK: call void @llvm.memset.p0.i64405 // CHECK: call void @_ZN6PR75561BD1Ev406 B();407 // CHECK: call void @llvm.memcpy.p0.p0.i64408 // CHECK: call void @_ZN6PR75561CD1Ev409 C();410 // CHECK-NEXT: ret void411 }412}413 414namespace Elision {415 struct A {416 A(); A(const A &); ~A();417 void *p;418 void foo() const;419 };420 421 void foo();422 A fooA();423 void takeA(A a);424 425 // CHECK-LABEL: define{{.*}} void @_ZN7Elision5test0Ev()426 void test0() {427 // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8428 // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8429 // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8430 // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8431 // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8432 433 // CHECK-NEXT: call void @_ZN7Elision3fooEv()434 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[I]])435 A i = (foo(), A());436 437 // CHECK-NEXT: call void @_ZN7Elision4fooAEv(ptr dead_on_unwind writable sret([[A]]) align 8 [[T0]])438 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[J]])439 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[T0]])440 A j = (fooA(), A());441 442 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[T1]])443 // CHECK-NEXT: call void @_ZN7Elision4fooAEv(ptr dead_on_unwind writable sret([[A]]) align 8 [[K]])444 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[T1]])445 A k = (A(), fooA());446 447 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[K]])448 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[J]])449 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[I]])450 }451 452 453 // CHECK-LABEL: define{{.*}} void @_ZN7Elision5test1EbNS_1AE(454 void test1(bool c, A x) {455 // CHECK: [[I:%.*]] = alloca [[A]], align 8456 // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8457 458 // CHECK: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[I]])459 // CHECK: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[I]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X:%.*]])460 A i = (c ? A() : x);461 462 // CHECK: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[J]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]])463 // CHECK: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[J]])464 A j = (c ? x : A());465 466 // CHECK: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[J]])467 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[I]])468 }469 470 // CHECK: define{{.*}} void @_ZN7Elision5test2Ev(ptr dead_on_unwind noalias writable sret([[A]]) align 8471 A test2() {472 // CHECK: call void @_ZN7Elision3fooEv()473 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[RET:%.*]])474 // CHECK-NEXT: ret void475 return (foo(), A());476 }477 478 // CHECK: define{{.*}} void @_ZN7Elision5test3EiNS_1AE(ptr dead_on_unwind noalias writable sret([[A]]) align 8479 A test3(int v, A x) {480 if (v < 5)481 // CHECK: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[RET:%.*]])482 // CHECK: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[RET]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X:%.*]])483 return (v < 0 ? A() : x);484 else485 // CHECK: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[RET]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]])486 // CHECK: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[RET]])487 return (v > 10 ? x : A());488 489 // CHECK: ret void490 }491 492 // CHECK-LABEL: define{{.*}} void @_ZN7Elision5test4Ev()493 void test4() {494 // CHECK: [[X:%.*]] = alloca [[A]], align 8495 // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16496 497 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[X]])498 A x;499 500 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[XS]])501 // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], ptr [[XS]], i64 1502 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[XS1]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]])503 A xs[] = { A(), x };504 505 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], ptr [[XS]], i32 0, i32 0506 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[BEGIN]], i64 2507 // CHECK-NEXT: br label508 // CHECK: [[AFTER:%.*]] = phi ptr509 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], ptr [[AFTER]], i64 -1510 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[CUR]])511 // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]]512 // CHECK-NEXT: br i1 [[T0]],513 514 // CHECK: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[X]])515 }516 517 // CHECK: define{{.*}} void @_ZN7Elision5test5Ev(ptr dead_on_unwind noalias writable sret([[A]]) align 8518 struct B { A a; B(); };519 A test5() {520 // CHECK: [[AT0:%.*]] = alloca [[A]], align 8521 // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8522 // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8523 // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8524 // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8525 526 // CHECK: call void @_ZN7Elision1BC1Ev(ptr {{[^,]*}} [[BT0]])527 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds nuw [[B]], ptr [[BT0]], i32 0, i32 0528 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[AT0]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[AM]])529 // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE(ptr noundef [[AT0]])530 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[AT0]])531 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev(ptr {{[^,]*}} [[BT0]])532 takeA(B().a);533 534 // CHECK-NEXT: call void @_ZN7Elision1BC1Ev(ptr {{[^,]*}} [[BT1]])535 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds nuw [[B]], ptr [[BT1]], i32 0, i32 0536 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[X]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[AM]])537 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev(ptr {{[^,]*}} [[BT1]])538 A x = B().a;539 540 // CHECK-NEXT: call void @_ZN7Elision1BC1Ev(ptr {{[^,]*}} [[BT2]])541 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds nuw [[B]], ptr [[BT2]], i32 0, i32 0542 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[RET:%.*]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[AM]])543 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev(ptr {{[^,]*}} [[BT2]])544 return B().a;545 546 // CHECK: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[X]])547 }548 549 // Reduced from webkit.550 // CHECK: define{{.*}} void @_ZN7Elision5test6EPKNS_1CE(ptr551 struct C { operator A() const; };552 void test6(const C *x) {553 // CHECK: [[T0:%.*]] = alloca [[A]], align 8554 // CHECK: [[X:%.*]] = load ptr, ptr {{%.*}}, align 8555 // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv(ptr dead_on_unwind writable sret([[A]]) align 8 [[T0]], ptr {{[^,]*}} [[X]])556 // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv(ptr {{[^,]*}} [[T0]])557 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[T0]])558 // CHECK-NEXT: ret void559 A(*x).foo();560 }561}562 563namespace PR8623 {564 struct A { A(int); ~A(); };565 566 // CHECK-LABEL: define{{.*}} void @_ZN6PR86233fooEb(567 void foo(bool b) {568 // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1569 // CHECK-NEXT: [[LCONS:%.*]] = alloca i1570 // CHECK-NEXT: [[RCONS:%.*]] = alloca i1571 // CHECK: store i1 false, ptr [[LCONS]]572 // CHECK-NEXT: store i1 false, ptr [[RCONS]]573 // CHECK-NEXT: br i1574 // CHECK: call void @_ZN6PR86231AC1Ei(ptr {{[^,]*}} [[TMP]], i32 noundef 2)575 // CHECK-NEXT: store i1 true, ptr [[LCONS]]576 // CHECK-NEXT: br label577 // CHECK: call void @_ZN6PR86231AC1Ei(ptr {{[^,]*}} [[TMP]], i32 noundef 3)578 // CHECK-NEXT: store i1 true, ptr [[RCONS]]579 // CHECK-NEXT: br label580 // CHECK: load i1, ptr [[RCONS]]581 // CHECK-NEXT: br i1582 // CHECK: call void @_ZN6PR86231AD1Ev(ptr {{[^,]*}} [[TMP]])583 // CHECK-NEXT: br label584 // CHECK: load i1, ptr [[LCONS]]585 // CHECK-NEXT: br i1586 // CHECK: call void @_ZN6PR86231AD1Ev(ptr {{[^,]*}} [[TMP]])587 // CHECK-NEXT: br label588 // CHECK: ret void589 b ? A(2) : A(3);590 }591}592 593namespace PR11365 {594 struct A { A(); ~A(); };595 596 // CHECK-LABEL: define{{.*}} void @_ZN7PR113653fooEv(597 void foo() {598 // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], ptr {{.*}}, i32 0, i32 0599 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[BEGIN]], i64 3600 // CHECK-NEXT: br label601 602 // CHECK: [[PHI:%.*]] = phi603 // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], ptr [[PHI]], i64 -1604 // CHECK-NEXT: call void @_ZN7PR113651AD1Ev(ptr {{[^,]*}} [[ELEM]])605 // CHECK-NEXT: icmp eq ptr [[ELEM]], [[BEGIN]]606 // CHECK-NEXT: br i1607 (void) (A [3]) {};608 }609}610 611namespace AssignmentOp {612 struct A { ~A(); };613 struct B { A operator=(const B&); };614 struct C : B { B b1, b2; };615 // CHECK-LABEL: define{{.*}} void @_ZN12AssignmentOp1fE616 void f(C &c1, const C &c2) {617 // CHECK: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_(618 c1 = c2;619 }620 621 // Ensure that each 'A' temporary is destroyed before the next subobject is622 // copied.623 // CHECK: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_(624 // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS625 // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(626 // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS627 // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(628 // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS629 // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(630}631 632namespace BindToSubobject {633 struct A {634 A();635 ~A();636 int a;637 };638 639 void f(), g();640 641 // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_)642 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN15BindToSubobject1AD1Ev, ptr @_ZGRN15BindToSubobject1aE_, ptr @__dso_handle)643 // CHECK: store ptr @_ZGRN15BindToSubobject1aE_, ptr @_ZN15BindToSubobject1aE, align 8644 int &&a = A().a;645 646 // CHECK: call void @_ZN15BindToSubobject1fEv()647 // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_)648 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN15BindToSubobject1AD1Ev, ptr @_ZGRN15BindToSubobject1bE_, ptr @__dso_handle)649 // CHECK: store ptr @_ZGRN15BindToSubobject1bE_, ptr @_ZN15BindToSubobject1bE, align 8650 int &&b = (f(), A().a);651 652 int A::*h();653 654 // CHECK: call void @_ZN15BindToSubobject1fEv()655 // CHECK: call void @_ZN15BindToSubobject1gEv()656 // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_)657 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN15BindToSubobject1AD1Ev, ptr @_ZGRN15BindToSubobject1cE_, ptr @__dso_handle)658 // CHECK: call {{.*}} @_ZN15BindToSubobject1hE659 // CHECK: getelementptr660 // CHECK: store ptr {{.*}}, ptr @_ZN15BindToSubobject1cE, align 8661 int &&c = (f(), (g(), A().*h()));662 663 struct B {664 int padding;665 A a;666 };667 668 // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_)669 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN15BindToSubobject1BD1Ev, ptr @_ZGRN15BindToSubobject1dE_, ptr @__dso_handle)670 // CHECK: call {{.*}} @_ZN15BindToSubobject1hE671 // CHECK: getelementptr {{.*}} getelementptr672 // CHECK: store ptr {{.*}}, ptr @_ZN15BindToSubobject1dE, align 8673 int &&d = (B().a).*h();674}675 676namespace Bitfield {677 struct S { int a : 5; ~S(); };678 679 // Do not lifetime extend the S() temporary here.680 // CHECK: alloca681 // CHECK: call {{.*}}memset682 // CHECK: store i32 {{.*}}, ptr @_ZGRN8Bitfield1rE_683 // CHECK: call void @_ZN8Bitfield1SD1684 // CHECK: store ptr @_ZGRN8Bitfield1rE_, ptr @_ZN8Bitfield1rE, align 8685 int &&r = S().a;686}687 688namespace ImplicitTemporaryCleanup {689 struct A { A(int); ~A(); };690 void g();691 692 // CHECK-LABEL: define{{.*}} void @_ZN24ImplicitTemporaryCleanup1fEv(693 void f() {694 // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei(695 A &&a = 0;696 697 // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv(698 g();699 700 // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev(701 }702}703 704namespace MultipleExtension {705 struct A { A(); ~A(); };706 struct B { B(); ~B(); };707 struct C { C(); ~C(); };708 struct D { D(); ~D(); int n; C c; };709 struct E { const A &a; B b; const C &c; ~E(); };710 711 E &&e1 = { A(), B(), D().c };712 713 // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]])714 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev, {{.*}} @[[TEMPA]]715 // CHECK: store {{.*}} @[[TEMPA]], {{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]],716 717 // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i64 8))718 719 // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]])720 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev, {{.*}} @[[TEMPD]]721 // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds nuw ({{.*}} @[[TEMPE]], i32 0, i32 2)722 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev, {{.*}} @[[TEMPE]]723 // CHECK: store {{.*}} @[[TEMPE]], ptr @_ZN17MultipleExtension2e1E, align 8724 725 E e2 = { A(), B(), D().c };726 727 // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]])728 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev, {{.*}} @[[TEMPA]]729 // CHECK: store {{.*}} @[[TEMPA]], {{.*}} @[[E:_ZN17MultipleExtension2e2E]]730 731 // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i64 8))732 733 // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]])734 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev, {{.*}} @[[TEMPD]]735 // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds nuw ({{.*}} @[[E]], i32 0, i32 2)736 // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev, {{.*}} @[[E]]737 738 739 void g();740 // CHECK: define{{.*}} void @[[NS:_ZN17MultipleExtension]]1fEv(741 void f() {742 E &&e1 = { A(), B(), D().c };743 // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0744 // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]])745 // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]]746 // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i64 8747 // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]])748 // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2749 // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]])750 // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i64 4751 // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]]752 // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]]753 754 g();755 // CHECK: call void @[[NS]]1gEv()756 757 E e2 = { A(), B(), D().c };758 // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0759 // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]])760 // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]]761 // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i64 8762 // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]])763 // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2764 // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]])765 // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i64 4766 // CHECK: store {{.*}} %[[TEMPD2_C]], ptr %[[TEMPE2_C]]767 768 g();769 // CHECK: call void @[[NS]]1gEv()770 771 // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[E2]])772 // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]])773 // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]])774 // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]])775 // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]])776 // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]])777 }778}779 780namespace ArrayAccess {781 struct A { A(int); ~A(); };782 void g();783 void f() {784 using T = A[3];785 786 // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 noundef 1787 // CHECK-NOT: @_ZN11ArrayAccess1AD788 // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 noundef 2789 // CHECK-NOT: @_ZN11ArrayAccess1AD790 // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 noundef 3791 // CHECK-NOT: @_ZN11ArrayAccess1AD792 A &&a = T{1, 2, 3}[1];793 794 // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 noundef 4795 // CHECK-NOT: @_ZN11ArrayAccess1AD796 // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 noundef 5797 // CHECK-NOT: @_ZN11ArrayAccess1AD798 // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 noundef 6799 // CHECK-NOT: @_ZN11ArrayAccess1AD800 A &&b = 2[T{4, 5, 6}];801 802 // CHECK: call void @_ZN11ArrayAccess1gEv(803 g();804 805 // CHECK: call void @_ZN11ArrayAccess1AD806 // CHECK: call void @_ZN11ArrayAccess1AD807 }808}809 810namespace PR14130 {811 struct S { S(int); };812 struct U { S &&s; };813 U v { { 0 } };814 // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 noundef 0)815 // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE816}817 818namespace Conditional {819 struct A {};820 struct B : A { B(); ~B(); };821 struct C : A { C(); ~C(); };822 823 void g();824 825 // CHECK-LABEL: define {{.*}} @_ZN11Conditional1fEb(826 void f(bool b) {827 // CHECK: store i1 false, ptr %[[CLEANUP_B:.*]],828 // CHECK: store i1 false, ptr %[[CLEANUP_C:.*]],829 // CHECK: br i1830 //831 // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev(832 // CHECK: store i1 true, ptr %[[CLEANUP_B]],833 // CHECK: br label834 //835 // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev(836 // CHECK: store i1 true, ptr %[[CLEANUP_C]],837 // CHECK: br label838 A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C());839 840 // CHECK: call {{.*}} @_ZN11Conditional1gEv(841 g();842 843 // CHECK: load {{.*}} %[[CLEANUP_C]]844 // CHECK: br i1845 // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev(846 // CHECK: br label847 848 // CHECK: load {{.*}} %[[CLEANUP_B]]849 // CHECK: br i1850 // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev(851 // CHECK: br label852 }853 854 struct D { A &&a; };855 // CHECK-LABEL: define {{.*}} @_ZN11Conditional10f_indirectEb(856 void f_indirect(bool b) {857 // CHECK: store i1 false, ptr %[[CLEANUP_B:.*]],858 // CHECK: store i1 false, ptr %[[CLEANUP_C:.*]],859 // CHECK: br i1860 //861 // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev(862 // CHECK: store i1 true, ptr %[[CLEANUP_B]],863 // CHECK: br label864 //865 // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev(866 // CHECK: store i1 true, ptr %[[CLEANUP_C]],867 // CHECK: br label868 D d = b ? D{B()} : D{C()};869 870 // In C++17, the expression D{...} directly initializes the 'd' object, so871 // lifetime-extending the temporaries to the lifetime of the D object872 // extends them past the call to g().873 //874 // In C++14 and before, D is move-constructed from the result of the875 // conditional expression, so no lifetime extension occurs.876 877 // CHECK-CXX17: call {{.*}} @_ZN11Conditional1gEv(878 879 // CHECK: load {{.*}} %[[CLEANUP_C]]880 // CHECK: br i1881 // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev(882 // CHECK: br label883 884 // CHECK: load {{.*}} %[[CLEANUP_B]]885 // CHECK: br i1886 // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev(887 // CHECK: br label888 889 // CHECK-CXX11: call {{.*}} @_ZN11Conditional1gEv(890 g();891 }892 893 extern bool b;894 // CHECK: load {{.*}} @_ZN11Conditional1b895 // CHECK: br i1896 //897 // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev({{.*}} @_ZGRN11Conditional1rE_)898 // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1BD1Ev, ptr @_ZGRN11Conditional1rE_,899 // CHECK: br label900 //901 // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev({{.*}} @_ZGRN11Conditional1rE0_)902 // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1CD1Ev, ptr @_ZGRN11Conditional1rE0_,903 // CHECK: br label904 A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C());905}906 907#if __cplusplus >= 201703L908namespace PR42220 {909 struct X { X(); ~X(); };910 struct A { X &&x; };911 struct B : A {};912 void g() noexcept;913 // CHECK-CXX17-LABEL: define{{.*}} @_ZN7PR422201fEv(914 void f() {915 // CHECK-CXX17: call{{.*}} @_ZN7PR422201XC1Ev(916 B &&b = {X()};917 // CHECK-CXX17-NOT: call{{.*}} @_ZN7PR422201XD1Ev(918 // CHECK-CXX17: call{{.*}} @_ZN7PR422201gEv(919 g();920 // CHECK-CXX17: call{{.*}} @_ZN7PR422201XD1Ev(921 }922}923#endif924