forked from OSchip/llvm-project
164 lines
5.7 KiB
C++
164 lines
5.7 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(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR]])
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR]])
|
||
|
// CHECK-DTOR: }
|
||
|
|
||
|
// CHECK-NO-DTOR-LABEL: Test1
|
||
|
// CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR]])
|
||
|
// CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR1:[0-9]+]])
|
||
|
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
|
||
|
// CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR2]])
|
||
|
// CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR1]])
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]])
|
||
|
// CHECK-DTOR: }
|
||
|
|
||
|
// CHECK-NO-DTOR-LABEL: Test2
|
||
|
// CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR2]])
|
||
|
// CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[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
|
||
|
// CHECK-DTOR: if.then:
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.end
|
||
|
// CHECK-DTOR: cleanup{{.*}}:
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.end
|
||
|
// CHECK-DTOR: 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
|
||
|
// CHECK-DTOR: for.cond.cleanup:
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.end
|
||
|
// CHECK-DTOR: 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(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]])
|
||
|
// CHECK-DTOR: call i32 @_Z3BazIiET_v()
|
||
|
// CHECK-DTOR: store
|
||
|
// CHECK-DTOR: call void @_Z3FooIiEvOT_
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]])
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]])
|
||
|
// CHECK-DTOR: call i32 @_Z3BazIiET_v()
|
||
|
// CHECK-DTOR: store
|
||
|
// CHECK-DTOR: call void @_Z3FooIiEvOT_
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.end(i64 {{[0-9]+}}, i8* %[[ADDR]])
|
||
|
// CHECK-DTOR: }
|
||
|
Foo(Baz<int>());
|
||
|
Foo(Baz<int>());
|
||
|
}
|
||
|
|
||
|
void Test7() {
|
||
|
// CHECK-DTOR-LABEL: Test7
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR]])
|
||
|
// CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[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(i64 1024, i8* %[[ADDR]])
|
||
|
// CHECK-DTOR: }
|
||
|
Foo(Baz<A>());
|
||
|
Foo(Baz<A>());
|
||
|
}
|