1 // RUN: %clang_cc1 %s -std=c++11 -O1 -DWITH_DTOR -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-DTOR %s 2 // RUN: %clang_cc1 %s -std=c++11 -O1 -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-NO-DTOR %s 3 4 struct A { 5 A(); 6 #ifdef WITH_DTOR 7 ~A(); 8 #endif 9 char a[1024]; 10 operator bool() const; 11 }; 12 13 template <typename T> 14 void Foo(T &&); 15 16 template <typename T> 17 void Bar(T &&); 18 19 template <typename T> 20 T Baz(); 21 22 void Test1() { 23 // CHECK-DTOR-LABEL: Test1 24 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 25 // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) 26 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ 27 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]]) 28 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]]) 29 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 30 // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) 31 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ 32 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]]) 33 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]]) 34 // CHECK-DTOR: } 35 36 // CHECK-NO-DTOR-LABEL: Test1 37 // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 38 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) 39 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ 40 // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]]) 41 // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 42 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) 43 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ 44 // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[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 56 void Test2() { 57 // CHECK-DTOR-LABEL: Test2 58 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR1:[0-9]+]]) 59 // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]]) 60 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ 61 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR2:[0-9]+]]) 62 // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]]) 63 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ 64 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR2]]) 65 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR2]]) 66 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR1]]) 67 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]]) 68 // CHECK-DTOR: } 69 70 // CHECK-NO-DTOR-LABEL: Test2 71 // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR1:[0-9]+]]) 72 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]]) 73 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ 74 // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR2:[0-9]+]]) 75 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]]) 76 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ 77 // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR2]]) 78 // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]]) 79 // CHECK-NO-DTOR: } 80 const A &a = A{}; 81 Foo(a); 82 const A &b = A{}; 83 Foo(b); 84 } 85 86 void Test3() { 87 // CHECK-DTOR-LABEL: Test3 88 // CHECK-DTOR: call void @llvm.lifetime.start 89 // CHECK-DTOR: call void @llvm.lifetime.start 90 91 // if.then: 92 // CHECK-DTOR: call void @llvm.lifetime.end 93 94 // cleanup: 95 // CHECK-DTOR: call void @llvm.lifetime.end 96 97 // cleanup: 98 // CHECK-DTOR: call void @llvm.lifetime.end 99 // 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 108 void Test4() { 109 // CHECK-DTOR-LABEL: Test4 110 // CHECK-DTOR: call void @llvm.lifetime.start 111 112 // for.cond.cleanup: 113 // CHECK-DTOR: call void @llvm.lifetime.end 114 115 // for.body: 116 // CHECK-DTOR: } 117 for (const A &a = A{}; a;) { 118 Foo(a); 119 } 120 } 121 122 int Test5() { 123 // CHECK-DTOR-LABEL: Test5 124 // CHECK-DTOR: call void @llvm.lifetime.start 125 // CHECK-DTOR: call i32 @_Z3BazIiET_v() 126 // CHECK-DTOR: store 127 // CHECK-DTOR: call void @_Z3FooIRKiEvOT_ 128 // CHECK-DTOR: load 129 // CHECK-DTOR: call void @llvm.lifetime.end 130 // CHECK-DTOR: } 131 const int &a = Baz<int>(); 132 Foo(a); 133 return a; 134 } 135 136 void Test6() { 137 // CHECK-DTOR-LABEL: Test6 138 // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]]) 139 // CHECK-DTOR: call i32 @_Z3BazIiET_v() 140 // CHECK-DTOR: store 141 // CHECK-DTOR: call void @_Z3FooIiEvOT_ 142 // CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]]) 143 // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]]) 144 // CHECK-DTOR: call i32 @_Z3BazIiET_v() 145 // CHECK-DTOR: store 146 // CHECK-DTOR: call void @_Z3FooIiEvOT_ 147 // CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]]) 148 // CHECK-DTOR: } 149 Foo(Baz<int>()); 150 Foo(Baz<int>()); 151 } 152 153 void Test7() { 154 // CHECK-DTOR-LABEL: Test7 155 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 156 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]]) 157 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]]) 158 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]]) 159 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]]) 160 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 161 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]]) 162 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]]) 163 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]]) 164 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]]) 165 // CHECK-DTOR: } 166 Foo(Baz<A>()); 167 Foo(Baz<A>()); 168 } 169