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