summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-03-01 19:42:53 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-03-01 19:42:53 +0000
commit25eb165f18a6479bcae7bcb338b22a2bfc4290fd (patch)
tree56d7d9e2e2d369bf0e15d1b80859a60dff5959af /clang
parentd2da0f0cace6ae715c2eb4e1053d1cc20665ae62 (diff)
downloadbcm5719-llvm-25eb165f18a6479bcae7bcb338b22a2bfc4290fd.tar.gz
bcm5719-llvm-25eb165f18a6479bcae7bcb338b22a2bfc4290fd.zip
[MSVC Compat] Correctly handle finallys nested within finallys
We'd lose track of the parent CodeGenFunction, leading us to get confused with regard to which function a nested finally belonged to. Differential Revision: http://reviews.llvm.org/D17752 llvm-svn: 262379
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGException.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h7
-rw-r--r--clang/test/CodeGen/exceptions-seh-finally.c25
4 files changed, 36 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index bf52152237d..3c730008326 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1625,14 +1625,13 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
SmallString<128> Name;
{
llvm::raw_svector_ostream OS(Name);
- const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
- const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
- assert(Parent && "FIXME: handle unnamed decls (lambdas, blocks) with SEH");
+ const FunctionDecl *ParentSEHFn = ParentCGF.CurSEHParent;
+ assert(ParentSEHFn && "No CurSEHParent!");
MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
if (IsFilter)
- Mangler.mangleSEHFilterExpression(Parent, OS);
+ Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
else
- Mangler.mangleSEHFinallyBlock(Parent, OS);
+ Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
}
FunctionArgList Args;
@@ -1679,6 +1678,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
+ CurSEHParent = ParentCGF.CurSEHParent;
CGM.SetLLVMFunctionAttributes(nullptr, FnInfo, CurFn);
EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 8e327c2bc4e..0e118b8f6f7 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -669,6 +669,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
DidCallStackSave = false;
CurCodeDecl = D;
+ if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D))
+ if (FD->usesSEHTry())
+ CurSEHParent = FD;
CurFuncDecl = (D ? D->getNonClosureContext() : nullptr);
FnRetTy = RetTy;
CurFn = Fn;
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 9a31c8f78b5..b9421fc0128 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -276,6 +276,8 @@ public:
/// potentially set the return value.
bool SawAsmBlock;
+ const FunctionDecl *CurSEHParent = nullptr;
+
/// True if the current function is an outlined SEH helper. This can be a
/// finally block or filter expression.
bool IsOutlinedSEHHelper;
@@ -1150,10 +1152,7 @@ public:
return getInvokeDestImpl();
}
- bool currentFunctionUsesSEHTry() const {
- const auto *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
- return FD && FD->usesSEHTry();
- }
+ bool currentFunctionUsesSEHTry() const { return CurSEHParent != nullptr; }
const TargetInfo &getTarget() const { return Target; }
llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }
diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c
index f0ed2230640..be1501f9e9d 100644
--- a/clang/test/CodeGen/exceptions-seh-finally.c
+++ b/clang/test/CodeGen/exceptions-seh-finally.c
@@ -230,3 +230,28 @@ int nested___finally___finally_with_eh_edge() {
// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
// CHECK: unreachable
+
+void finally_within_finally() {
+ __try {
+ might_crash();
+ } __finally {
+ __try {
+ might_crash();
+ } __finally {
+ }
+ }
+}
+
+// CHECK-LABEL: define void @finally_within_finally(
+// CHECK: invoke void @might_crash(
+
+// CHECK: call void @"\01?fin$0@0@finally_within_finally@@"(
+// CHECK: call void @"\01?fin$0@0@finally_within_finally@@"({{.*}}) [ "funclet"(
+
+// CHECK-LABEL: define internal void @"\01?fin$0@0@finally_within_finally@@"(
+// CHECK: invoke void @might_crash(
+
+// CHECK: call void @"\01?fin$1@0@finally_within_finally@@"(
+// CHECK: call void @"\01?fin$1@0@finally_within_finally@@"({{.*}}) [ "funclet"(
+
+// CHECK-LABEL: define internal void @"\01?fin$1@0@finally_within_finally@@"(
OpenPOWER on IntegriCloud