r230460 - Produce less broken basic block sequences for __finally blocks.

Nico Weber nicolasweber at gmx.de
Tue Feb 24 20:05:18 PST 2015


Author: nico
Date: Tue Feb 24 22:05:18 2015
New Revision: 230460

URL: http://llvm.org/viewvc/llvm-project?rev=230460&view=rev
Log:
Produce less broken basic block sequences for __finally blocks.

The way cleanups (such as PerformSEHFinally) get emitted is that codegen
generates some initialization code, then calls the cleanup's Emit() with the
insertion point set to a good place, then the cleanup is supposed to emit its
stuff, and then codegen might tack in a jump or similar to where the insertion
point is after the cleanup.

The PerformSEHFinally cleanup tries to just stash away the block it's supposed
to codegen into, and then does codegen later, into that stashed block.  However,
after codegen'ing the __finally block, it used to set the insertion point to
the finally's continuation block (where the __finally cleanup goes when its body
is completed after regular, non-exceptional control flow).  That's not correct,
as that block can (and generally does) already ends in a jump.  Instead,
remember the insertion point that was current before the __finally got emitted,
and restore that.

Fixes two of the crashes in PR22553.

Modified:
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/test/CodeGen/exceptions-seh-finally.c

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=230460&r1=230459&r2=230460&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Feb 24 22:05:18 2015
@@ -813,8 +813,8 @@ llvm::BasicBlock *CodeGenFunction::EmitL
   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(con
     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(con
       Builder.CreateBr(FI.ContBB);
     }
 
-    Builder.SetInsertPoint(FI.ContBB);
+    Builder.restoreIP(SavedIP);
 
     return;
   }

Modified: cfe/trunk/test/CodeGen/exceptions-seh-finally.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-finally.c?rev=230460&r1=230459&r2=230460&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-finally.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-finally.c Tue Feb 24 22:05:18 2015
@@ -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* %cleanup.dest.slot
+// CHECK-NEXT:  store i8 0, i8* %abnormal.termination.slot
+// CHECK-NEXT: br label %[[outerfinally:[^ ]*]]
+//
+// CHECK: [[outerfinally]]
+// CHECK-NEXT: br label %[[finallycont:[^ ]*]]
+//
+// CHECK: [[finallycont]]
+// CHECK-NEXT: ret i32 1





More information about the cfe-commits mailing list