Don't promote asynch EH invokes of nounwind functions to calls

If the landingpad of the invoke is using a personality function that
catches asynch exceptions, then it can catch a trap.

Also add some landingpads to invalid LLVM IR test cases that lack them.

Over-the-shoulder reviewed by David Majnemer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228782 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Kleckner
2015-02-11 01:23:16 +00:00
parent 9f5d593c1f
commit 690248bf52
13 changed files with 150 additions and 27 deletions

View File

@@ -64,7 +64,7 @@ LibCallInfo::getFunctionInfo(const Function *F) const {
/// See if the given exception handling personality function is one that we
/// understand. If so, return a description of it; otherwise return Unknown.
EHPersonality llvm::ClassifyEHPersonality(Value *Pers) {
EHPersonality llvm::classifyEHPersonality(Value *Pers) {
Function *F = dyn_cast<Function>(Pers->stripPointerCasts());
if (!F)
return EHPersonality::Unknown;
@@ -73,7 +73,30 @@ EHPersonality llvm::ClassifyEHPersonality(Value *Pers) {
.Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
.Case("__gcc_personality_v0", EHPersonality::GNU_C)
.Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
.Case("__except_handler3", EHPersonality::MSVC_X86SEH)
.Case("__except_handler4", EHPersonality::MSVC_X86SEH)
.Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH)
.Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
.Default(EHPersonality::Unknown);
}
bool llvm::isAsynchronousEHPersonality(EHPersonality Pers) {
// The two SEH personality functions can catch asynch exceptions. We assume
// unknown personalities don't catch asynch exceptions.
switch (Pers) {
case EHPersonality::MSVC_X86SEH:
case EHPersonality::MSVC_Win64SEH:
return true;
default: return false;
}
llvm_unreachable("invalid enum");
}
bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) {
const LandingPadInst *LP = II->getLandingPadInst();
EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn());
// We can't simplify any invokes to nounwind functions if the personality
// function wants to catch asynch exceptions. The nounwind attribute only
// implies that the function does not throw synchronous exceptions.
return !isAsynchronousEHPersonality(Personality);
}