[MS ABI] Don't rely on terminatepad

We'd like to remove support for terminatepad from LLVM.  To do this, we
need to move Clang off of it first.  The intent behind terminatepad was
to carefully model exception specifications for the MSVC personality.

However, we don't support exception specifications for the MSVC
personality and neither does MSVC.  Instead, MSVC supports
all-or-nothing exception specifications.  We can model this limited
usage using cleanuppads which call std::terminate.

Differential Revision: http://reviews.llvm.org/D15478

llvm-svn: 255521
This commit is contained in:
David Majnemer 2015-12-14 18:34:18 +00:00
parent accc3e0376
commit feeefb214d
3 changed files with 11 additions and 10 deletions

View File

@ -1325,21 +1325,20 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
// end of the function by FinishFunction. // end of the function by FinishFunction.
TerminateHandler = createBasicBlock("terminate.handler"); TerminateHandler = createBasicBlock("terminate.handler");
Builder.SetInsertPoint(TerminateHandler); Builder.SetInsertPoint(TerminateHandler);
llvm::Value *Exn = nullptr;
if (EHPersonality::get(*this).usesFuncletPads()) { if (EHPersonality::get(*this).usesFuncletPads()) {
llvm::Value *ParentPad = CurrentFuncletPad; llvm::Value *ParentPad = CurrentFuncletPad;
if (!ParentPad) if (!ParentPad)
ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext()); ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
Builder.CreateTerminatePad(ParentPad, /*UnwindBB=*/nullptr, Builder.CreateCleanupPad(ParentPad);
{CGM.getTerminateFn()});
} else { } else {
llvm::Value *Exn = nullptr;
if (getLangOpts().CPlusPlus) if (getLangOpts().CPlusPlus)
Exn = getExceptionFromSlot(); Exn = getExceptionFromSlot();
}
llvm::CallInst *terminateCall = llvm::CallInst *terminateCall =
CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn); CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
terminateCall->setDoesNotReturn(); terminateCall->setDoesNotReturn();
Builder.CreateUnreachable(); Builder.CreateUnreachable();
}
// Restore the saved insertion state. // Restore the saved insertion state.
Builder.restoreIP(SavedIP); Builder.restoreIP(SavedIP);

View File

@ -72,5 +72,6 @@ void test_cleanup() {
// CHECK: ret void // CHECK: ret void
// CHECK: [[TERMINATE]] // CHECK: [[TERMINATE]]
// CHECK: terminatepad within none [void ()* @"\01?terminate@@YAXXZ"] unwind to caller // CHECK: cleanuppad within none []
// CHECK-NEXT: call void @"\01?terminate@@YAXXZ"()

View File

@ -9,6 +9,7 @@ void never_throws() noexcept(true) {
// CHECK-LABEL: define void @"\01?never_throws@@YAXXZ"() // CHECK-LABEL: define void @"\01?never_throws@@YAXXZ"()
// CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) // CHECK-SAME: personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
// CHECK: invoke void @"\01?may_throw@@YAXXZ"() // CHECK: invoke void @"\01?may_throw@@YAXXZ"()
// MSVC2013: terminatepad within none [void ()* @"\01?terminate@@YAXXZ"] // CHECK: cleanuppad within none []
// MSVC2015: terminatepad within none [void ()* @__std_terminate] // MSVC2013: call void @"\01?terminate@@YAXXZ"()
// MSVC2015: call void @__std_terminate()
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable