diff options
author | Sanjin Sijaric <ssijaric@codeaurora.org> | 2019-01-16 07:39:44 +0000 |
---|---|---|
committer | Sanjin Sijaric <ssijaric@codeaurora.org> | 2019-01-16 07:39:44 +0000 |
commit | 6177eda8577856233853ed2c036617e320c48126 (patch) | |
tree | b493ec005213ba078fa287edc42ea5d4fb6bed61 | |
parent | fb1f12a1e98dbd88abc0650c644f7202d6149bd1 (diff) |
[SEH] Pass the frame pointer from SEH finally to finally functionslinaro-local/ci/tcwg_kernel/llvm-master-arm-stable-allyesconfig
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
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 12 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh-nested-finally.c | 26 |
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; +} |