diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2016-04-01 22:58:55 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2016-04-01 22:58:55 +0000 |
commit | 8af7bb28aa225fe30e0a682325b5b9f4df74d6fe (patch) | |
tree | 2c57e78d83e44e464a746ae2151cde903978202d /clang/test/CodeGenCXX/destructors.cpp | |
parent | 58a15d5a235c57aafdc881250c25d8ce37a0f47e (diff) | |
download | bcm5719-llvm-8af7bb28aa225fe30e0a682325b5b9f4df74d6fe.tar.gz bcm5719-llvm-8af7bb28aa225fe30e0a682325b5b9f4df74d6fe.zip |
[CodeGen] Emit lifetime.end intrinsic after objects are destructed in
landing pads.
Previously, lifetime.end intrinsics were inserted only on normal control
flows. This prevented StackColoring from merging stack slots for objects
that were destroyed on the exception handling control flow since it
couldn't tell their lifetime ranges were disjoint. This patch fixes
code-gen to emit the intrinsic on both control flows.
rdar://problem/22181976
Differential Revision: http://reviews.llvm.org/D18196
llvm-svn: 265197
Diffstat (limited to 'clang/test/CodeGenCXX/destructors.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/destructors.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp index 529603142d3..d6aabee58b9 100644 --- a/clang/test/CodeGenCXX/destructors.cpp +++ b/clang/test/CodeGenCXX/destructors.cpp @@ -4,6 +4,9 @@ // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s // RUN: FileCheck --check-prefix=CHECK4 --input-file=%t %s // RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns -std=c++11 > %t2 +// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t2 %s +// REQUIRES: asserts struct A { int a; @@ -428,3 +431,64 @@ namespace test10 { return true; } } + +#if __cplusplus >= 201103L +namespace test11 { + +// Check that lifetime.end is emitted in the landing pad. + +// CHECK6-LABEL: define void @_ZN6test1115testLifetimeEndEi( +// CHECK6: entry: +// CHECK6: [[T1:%[a-z0-9]+]] = alloca %"struct.test11::S1" +// CHECK6: [[T2:%[a-z0-9]+]] = alloca %"struct.test11::S1" +// CHECK6: [[T3:%[a-z0-9]+]] = alloca %"struct.test11::S1" + +// CHECK6: {{^}}invoke.cont +// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T1]]) +// CHECK6: [[BC1:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T1]] to i8* +// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC1]]) +// CHECK6: {{^}}lpad +// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T1]]) +// CHECK6: [[BC2:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T1]] to i8* +// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC2]]) + +// CHECK6: {{^}}invoke.cont +// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T2]]) +// CHECK6: [[BC3:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T2]] to i8* +// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC3]]) +// CHECK6: {{^}}lpad +// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T2]]) +// CHECK6: [[BC4:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T2]] to i8* +// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC4]]) + +// CHECK6: {{^}}invoke.cont +// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T3]]) +// CHECK6: [[BC5:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T3]] to i8* +// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC5]]) +// CHECK6: {{^}}lpad +// CHECK6: call void @_ZN6test112S1D1Ev(%"struct.test11::S1"* [[T3]]) +// CHECK6: [[BC6:%[a-z0-9]+]] = bitcast %"struct.test11::S1"* [[T3]] to i8* +// CHECK6: call void @llvm.lifetime.end(i64 32, i8* [[BC6]]) + + struct S1 { + ~S1(); + int a[8]; + }; + + void func1(S1 &) noexcept(false); + + void testLifetimeEnd(int n) { + if (n < 10) { + S1 t1; + func1(t1); + } else if (n < 100) { + S1 t2; + func1(t2); + } else if (n < 1000) { + S1 t3; + func1(t3); + } + } + +} +#endif |