summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjin Sijaric <ssijaric@codeaurora.org>2019-01-16 07:39:44 +0000
committerSanjin Sijaric <ssijaric@codeaurora.org>2019-01-16 07:39:44 +0000
commitcfa2a2afa64890858999ab9510627712c0f5e4f9 (patch)
tree2587a5d0be6b848c3518813a26a56a3b12f43265
parent94d6dd4c082412d7914babffb8b7eee28b985d1f (diff)
downloadbcm5719-llvm-cfa2a2afa64890858999ab9510627712c0f5e4f9.tar.gz
bcm5719-llvm-cfa2a2afa64890858999ab9510627712c0f5e4f9.zip
[SEH] Pass the frame pointer from SEH finally to finally functions
Pass the frame pointer that the first finally block receives onto the nested finally block, instead of generating it using localaddr. Differential Revision: https://reviews.llvm.org/D56463 llvm-svn: 351302
-rw-r--r--clang/lib/CodeGen/CGException.cpp12
-rw-r--r--clang/test/CodeGen/exceptions-seh-nested-finally.c26
2 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index dd4298cc57f..5756e13d262 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1627,8 +1627,16 @@ struct PerformSEHFinally final : EHScopeStack::Cleanup {
// Compute the two argument values.
QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
- llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
- llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
+ llvm::Value *FP = nullptr;
+ // If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
+ if (CGF.IsOutlinedSEHHelper) {
+ FP = &CGF.CurFn->arg_begin()[1];
+ } else {
+ llvm::Value *LocalAddrFn =
+ CGM.getIntrinsic(llvm::Intrinsic::localaddress);
+ FP = CGF.Builder.CreateCall(LocalAddrFn);
+ }
+
llvm::Value *IsForEH =
llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
Args.add(RValue::get(IsForEH), ArgTys[0]);
diff --git a/clang/test/CodeGen/exceptions-seh-nested-finally.c b/clang/test/CodeGen/exceptions-seh-nested-finally.c
new file mode 100644
index 00000000000..7385d18f0cd
--- /dev/null
+++ b/clang/test/CodeGen/exceptions-seh-nested-finally.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check that the first finally block passes the enclosing function's frame
+// pointer to the second finally block, instead of generating it via localaddr.
+
+// CHECK-LABEL: define internal void @"?fin$0@0@main@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
+// CHECK: call void @"?fin$1@0@main@@"({{i8( zeroext)?}} 0, i8* %frame_pointer)
+int
+main() {
+ int Check = 0;
+ __try {
+ Check = 3;
+ } __finally {
+ __try {
+ Check += 2;
+ } __finally {
+ Check += 4;
+ }
+ }
+ return Check;
+}
OpenPOWER on IntegriCloud