diff options
| -rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 7 | ||||
| -rw-r--r-- | clang/test/CodeGen/exceptions-seh-finally.c | 42 |
2 files changed, 46 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 61f538b0eec..b7953bcedc9 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -813,8 +813,8 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { bool hasFilter = false; SmallVector<llvm::Value*, 4> filterTypes; llvm::SmallPtrSet<llvm::Value*, 4> catchTypes; - for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); - I != E; ++I) { + for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); I != E; + ++I) { switch (I->getKind()) { case EHScope::Cleanup: @@ -1927,6 +1927,7 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI) { assert(FI.ContBB && "did not emit normal cleanup"); // Emit the code into FinallyBB. + CGBuilderTy::InsertPoint SavedIP = Builder.saveIP(); Builder.SetInsertPoint(FI.FinallyBB); EmitStmt(Finally->getBlock()); @@ -1949,7 +1950,7 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI) { Builder.CreateBr(FI.ContBB); } - Builder.SetInsertPoint(FI.ContBB); + Builder.restoreIP(SavedIP); return; } diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c index 4cd82d0972e..64b3ffdf187 100644 --- a/clang/test/CodeGen/exceptions-seh-finally.c +++ b/clang/test/CodeGen/exceptions-seh-finally.c @@ -160,3 +160,45 @@ void noreturn_finally() { // CHECK-NEXT: cleanup // CHECK: store i8 1, i8* % // CHECK: br label %[[finally]] + +int finally_with_return() { + __try { + return 42; + } __finally { + } +} +// CHECK-LABEL: define i32 @finally_with_return() +// CHECK: store i8 0, i8* % +// CHECK-NEXT: br label %[[finally:[^ ]*]] +// +// CHECK: [[finally]] +// CHECK-NEXT: br label %[[finallycont:[^ ]*]] +// +// CHECK: [[finallycont]] +// CHECK-NEXT: ret i32 42 + +int nested___finally___finally() { + __try { + __try { + } __finally { + return 1; + } + } __finally { + // Intentionally no return here. + } + return 0; +} +// CHECK-LABEL: define i32 @nested___finally___finally +// CHECK: store i8 0, i8* % +// CHECK-NEXT: br label %[[finally:[^ ]*]] +// +// CHECK: [[finally]] +// CHECK-NEXT: store i32 1, i32* % +// CHECK-NEXT: store i8 0, i8* % +// CHECK-NEXT: br label %[[outerfinally:[^ ]*]] +// +// CHECK: [[outerfinally]] +// CHECK-NEXT: br label %[[finallycont:[^ ]*]] +// +// CHECK: [[finallycont]] +// CHECK-NEXT: ret i32 1 |

