summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGException.cpp7
-rw-r--r--clang/test/CodeGen/exceptions-seh-finally.c42
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
OpenPOWER on IntegriCloud