Fix crash on finally blocks that don't fall through
llvm-svn: 228243
This commit is contained in:
parent
9c26d80c18
commit
16f9a6b43d
|
@ -1902,12 +1902,20 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI) {
|
|||
// 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");
|
||||
|
|
|
@ -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]]
|
||||
|
|
Loading…
Reference in New Issue