169 lines · cpp
1// RUN: %clang_cc1 -no-enable-noundef-analysis %s -std=c++11 -O1 -DWITH_DTOR -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-DTOR %s2// RUN: %clang_cc1 -no-enable-noundef-analysis %s -std=c++11 -O1 -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-NO-DTOR %s3 4struct A {5 A();6#ifdef WITH_DTOR7 ~A();8#endif9 char a[1024];10 operator bool() const;11};12 13template <typename T>14void Foo(T &&);15 16template <typename T>17void Bar(T &&);18 19template <typename T>20T Baz();21 22void Test1() {23 // CHECK-DTOR-LABEL: Test124 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])25 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])26 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_27 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR]])28 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])29 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])30 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])31 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_32 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR]])33 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])34 // CHECK-DTOR: }35 36 // CHECK-NO-DTOR-LABEL: Test137 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])38 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])39 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_40 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])41 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])42 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])43 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_44 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])45 // CHECK-NO-DTOR: }46 {47 const A &a = A{};48 Foo(a);49 }50 {51 const A &a = A{};52 Foo(a);53 }54}55 56void Test2() {57 // CHECK-DTOR-LABEL: Test258 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR1:.+]])59 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR1:[^ ]+]])60 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_61 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR2:.+]])62 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR2:[^ ]+]])63 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_64 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR2]])65 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR2]])66 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR1]])67 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR1]])68 // CHECK-DTOR: }69 70 // CHECK-NO-DTOR-LABEL: Test271 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR1:.+]])72 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR1:[^ ]+]])73 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_74 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR2:.+]])75 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR2:[^ ]+]])76 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_77 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR2]])78 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR1]])79 // CHECK-NO-DTOR: }80 const A &a = A{};81 Foo(a);82 const A &b = A{};83 Foo(b);84}85 86void Test3() {87 // CHECK-DTOR-LABEL: Test388 // CHECK-DTOR: call void @llvm.lifetime.start89 // CHECK-DTOR: call void @llvm.lifetime.start90 91 // if.then:92 // CHECK-DTOR: call void @llvm.lifetime.end93 94 // cleanup:95 // CHECK-DTOR: call void @llvm.lifetime.end96 97 // cleanup:98 // CHECK-DTOR: call void @llvm.lifetime.end99 // CHECK-DTOR: }100 const A &a = A{};101 if (const A &b = A(a)) {102 Foo(b);103 return;104 }105 Bar(a);106}107 108void Test4() {109 // CHECK-DTOR-LABEL: Test4110 // CHECK-DTOR: call void @llvm.lifetime.start111 112 // for.cond.cleanup:113 // CHECK-DTOR: call void @llvm.lifetime.end114 115 // for.body:116 // CHECK-DTOR: }117 for (const A &a = A{}; a;) {118 Foo(a);119 }120}121 122int Test5() {123 // CHECK-DTOR-LABEL: Test5124 // CHECK-DTOR: call void @llvm.lifetime.start125 // CHECK-DTOR: call i32 @_Z3BazIiET_v()126 // CHECK-DTOR: store127 // CHECK-DTOR: call void @_Z3FooIRKiEvOT_128 // CHECK-DTOR: load129 // CHECK-DTOR: call void @llvm.lifetime.end130 // CHECK-DTOR: }131 const int &a = Baz<int>();132 Foo(a);133 return a;134}135 136void Test6() {137 // CHECK-DTOR-LABEL: Test6138 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])139 // CHECK-DTOR: call i32 @_Z3BazIiET_v()140 // CHECK-DTOR: store141 // CHECK-DTOR: call void @_Z3FooIiEvOT_142 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])143 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])144 // CHECK-DTOR: call i32 @_Z3BazIiET_v()145 // CHECK-DTOR: store146 // CHECK-DTOR: call void @_Z3FooIiEvOT_147 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])148 // CHECK-DTOR: }149 Foo(Baz<int>());150 Foo(Baz<int>());151}152 153void Test7() {154 // CHECK-DTOR-LABEL: Test7155 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])156 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])157 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])158 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[SLOT]])159 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])160 // CHECK-DTOR: call void @llvm.lifetime.start.p0(ptr nonnull %[[ADDR:.+]])161 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])162 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])163 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[SLOT]])164 // CHECK-DTOR: call void @llvm.lifetime.end.p0(ptr nonnull %[[ADDR]])165 // CHECK-DTOR: }166 Foo(Baz<A>());167 Foo(Baz<A>());168}169