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 // CHECK-DTOR: if.then: 91 // CHECK-DTOR: call void @llvm.lifetime.end 92 // CHECK-DTOR: cleanup{{.*}}: 93 // CHECK-DTOR: call void @llvm.lifetime.end 94 // CHECK-DTOR: cleanup{{.*}}: 95 // CHECK-DTOR: call void @llvm.lifetime.end 96 // CHECK-DTOR: } 97 const A &a = A{}; 98 if (const A &b = A(a)) { 99 Foo(b); 100 return; 101 } 102 Bar(a); 103 } 104 105 void Test4() { 106 // CHECK-DTOR-LABEL: Test4 107 // CHECK-DTOR: call void @llvm.lifetime.start 108 // CHECK-DTOR: for.cond.cleanup: 109 // CHECK-DTOR: call void @llvm.lifetime.end 110 // CHECK-DTOR: for.body: 111 // CHECK-DTOR: } 112 for (const A &a = A{}; a;) { 113 Foo(a); 114 } 115 } 116 117 int Test5() { 118 // CHECK-DTOR-LABEL: Test5 119 // CHECK-DTOR: call void @llvm.lifetime.start 120 // CHECK-DTOR: call i32 @_Z3BazIiET_v() 121 // CHECK-DTOR: store 122 // CHECK-DTOR: call void @_Z3FooIRKiEvOT_ 123 // CHECK-DTOR: load 124 // CHECK-DTOR: call void @llvm.lifetime.end 125 // CHECK-DTOR: } 126 const int &a = Baz<int>(); 127 Foo(a); 128 return a; 129 } 130 131 void Test6() { 132 // CHECK-DTOR-LABEL: Test6 133 // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]]) 134 // CHECK-DTOR: call i32 @_Z3BazIiET_v() 135 // CHECK-DTOR: store 136 // CHECK-DTOR: call void @_Z3FooIiEvOT_ 137 // CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]]) 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: } 144 Foo(Baz<int>()); 145 Foo(Baz<int>()); 146 } 147 148 void Test7() { 149 // CHECK-DTOR-LABEL: Test7 150 // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]]) 151 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]]) 152 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]]) 153 // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]]) 154 // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]]) 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: } 161 Foo(Baz<A>()); 162 Foo(Baz<A>()); 163 } 164