169 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| // 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>());
 | |
| }
 |