r228243 - Fix crash on finally blocks that don't fall through

Reid Kleckner reid at kleckner.net
Wed Feb 4 16:58:46 PST 2015


Author: rnk
Date: Wed Feb  4 18:58:46 2015
New Revision: 228243

URL: http://llvm.org/viewvc/llvm-project?rev=228243&view=rev
Log:
Fix crash on finally blocks that don't fall through

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=228243&r1=228242&r2=228243&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Wed Feb  4 18:58:46 2015
@@ -1902,12 +1902,20 @@ void CodeGenFunction::ExitSEHTryStmt(con
   // Just pop the cleanup if it's a __finally block.
   if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
     PopCleanupBlock();
+    assert(FI.ContBB && "did not emit normal cleanup");
 
     // Emit the code into FinallyBB.
     Builder.SetInsertPoint(FI.FinallyBB);
     EmitStmt(Finally->getBlock());
 
-    assert(FI.ContBB);
+    // If the finally block doesn't fall through, we don't need these blocks.
+    if (!HaveInsertPoint()) {
+      FI.ContBB->eraseFromParent();
+      if (FI.ResumeBB)
+        FI.ResumeBB->eraseFromParent();
+      return;
+    }
+
     if (FI.ResumeBB) {
       llvm::Value *IsEH = Builder.CreateLoad(getAbnormalTerminationSlot(),
                                              "abnormal.termination");

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=228243&r1=228242&r2=228243&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-finally.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-finally.c Wed Feb  4 18:58:46 2015
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fexceptions -fms-extensions -emit-llvm -o - | FileCheck %s
 
+void abort(void) __attribute__((noreturn));
 void might_crash(void);
 void cleanup(void);
 int check_condition(void);
@@ -117,3 +118,45 @@ void use_abnormal_termination(void) {
 //
 // CHECK: [[ehresume]]
 // CHECK: resume { i8*, i32 }
+
+void noreturn_noop_finally() {
+  __try {
+    __noop();
+  } __finally {
+    abort();
+  }
+}
+
+// CHECK-LABEL: define void @noreturn_noop_finally()
+// CHECK: store i8 0, i8* %
+// CHECK: br label %[[finally:[^ ]*]]
+// CHECK: [[finally]]
+// CHECK: call void @abort()
+// CHECK-NEXT: unreachable
+// CHECK-NOT: load
+
+void noreturn_finally() {
+  __try {
+    might_crash();
+  } __finally {
+    abort();
+  }
+}
+
+// CHECK-LABEL: define void @noreturn_finally()
+// CHECK: invoke void @might_crash()
+// CHECK:     to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+//
+// CHECK: [[cont]]
+// CHECK: store i8 0, i8* %
+// CHECK: br label %[[finally:[^ ]*]]
+//
+// CHECK: [[finally]]
+// CHECK: call void @abort()
+// CHECK-NEXT: unreachable
+//
+// CHECK: [[lpad]]
+// CHECK: landingpad
+// CHECK-NEXT: cleanup
+// CHECK: store i8 1, i8* %
+// CHECK: br label %[[finally]]





More information about the cfe-commits mailing list