|  | // RUN: %clang_cc1 %s -std=c++11 -O1 -DWITH_DTOR -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-DTOR %s | 
|  | // RUN: %clang_cc1 %s -std=c++11 -O1 -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-NO-DTOR %s | 
|  |  | 
|  | struct A { | 
|  | A(); | 
|  | #ifdef WITH_DTOR | 
|  | ~A(); | 
|  | #endif | 
|  | char a[1024]; | 
|  | operator bool() const; | 
|  | }; | 
|  |  | 
|  | template <typename T> | 
|  | void Foo(T &&); | 
|  |  | 
|  | template <typename T> | 
|  | void Bar(T &&); | 
|  |  | 
|  | template <typename T> | 
|  | T Baz(); | 
|  |  | 
|  | void Test1() { | 
|  | // CHECK-DTOR-LABEL: Test1 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) | 
|  | // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) | 
|  | // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-DTOR: } | 
|  |  | 
|  | // CHECK-NO-DTOR-LABEL: Test1 | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) | 
|  | // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]]) | 
|  | // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-NO-DTOR: } | 
|  | { | 
|  | const A &a = A{}; | 
|  | Foo(a); | 
|  | } | 
|  | { | 
|  | const A &a = A{}; | 
|  | Foo(a); | 
|  | } | 
|  | } | 
|  |  | 
|  | void Test2() { | 
|  | // CHECK-DTOR-LABEL: Test2 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR1:[0-9]+]]) | 
|  | // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]]) | 
|  | // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR2:[0-9]+]]) | 
|  | // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]]) | 
|  | // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR2]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR2]]) | 
|  | // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR1]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR1]]) | 
|  | // CHECK-DTOR: } | 
|  |  | 
|  | // CHECK-NO-DTOR-LABEL: Test2 | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR1:[0-9]+]]) | 
|  | // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]]) | 
|  | // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR2:[0-9]+]]) | 
|  | // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]]) | 
|  | // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_ | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR2]]) | 
|  | // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR1]]) | 
|  | // CHECK-NO-DTOR: } | 
|  | const A &a = A{}; | 
|  | Foo(a); | 
|  | const A &b = A{}; | 
|  | Foo(b); | 
|  | } | 
|  |  | 
|  | void Test3() { | 
|  | // CHECK-DTOR-LABEL: Test3 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start | 
|  |  | 
|  | // if.then: | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end | 
|  |  | 
|  | // cleanup: | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end | 
|  |  | 
|  | // cleanup: | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end | 
|  | // CHECK-DTOR: } | 
|  | const A &a = A{}; | 
|  | if (const A &b = A(a)) { | 
|  | Foo(b); | 
|  | return; | 
|  | } | 
|  | Bar(a); | 
|  | } | 
|  |  | 
|  | void Test4() { | 
|  | // CHECK-DTOR-LABEL: Test4 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start | 
|  |  | 
|  | // for.cond.cleanup: | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end | 
|  |  | 
|  | // for.body: | 
|  | // CHECK-DTOR: } | 
|  | for (const A &a = A{}; a;) { | 
|  | Foo(a); | 
|  | } | 
|  | } | 
|  |  | 
|  | int Test5() { | 
|  | // CHECK-DTOR-LABEL: Test5 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start | 
|  | // CHECK-DTOR: call i32 @_Z3BazIiET_v() | 
|  | // CHECK-DTOR: store | 
|  | // CHECK-DTOR: call void @_Z3FooIRKiEvOT_ | 
|  | // CHECK-DTOR: load | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end | 
|  | // CHECK-DTOR: } | 
|  | const int &a = Baz<int>(); | 
|  | Foo(a); | 
|  | return a; | 
|  | } | 
|  |  | 
|  | void Test6() { | 
|  | // CHECK-DTOR-LABEL: Test6 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 {{[0-9]+}}, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-DTOR: call i32 @_Z3BazIiET_v() | 
|  | // CHECK-DTOR: store | 
|  | // CHECK-DTOR: call void @_Z3FooIiEvOT_ | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 {{[0-9]+}}, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 {{[0-9]+}}, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-DTOR: call i32 @_Z3BazIiET_v() | 
|  | // CHECK-DTOR: store | 
|  | // CHECK-DTOR: call void @_Z3FooIiEvOT_ | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 {{[0-9]+}}, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-DTOR: } | 
|  | Foo(Baz<int>()); | 
|  | Foo(Baz<int>()); | 
|  | } | 
|  |  | 
|  | void Test7() { | 
|  | // CHECK-DTOR-LABEL: Test7 | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]]) | 
|  | // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]]) | 
|  | // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]]) | 
|  | // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]]) | 
|  | // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]]) | 
|  | // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]]) | 
|  | // CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]]) | 
|  | // CHECK-DTOR: } | 
|  | Foo(Baz<A>()); | 
|  | Foo(Baz<A>()); | 
|  | } |