diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-02-11 01:23:16 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-02-11 01:23:16 +0000 |
commit | 96d011315aa01de179897eaf4e7baeddc5de1cda (patch) | |
tree | ccced202122ff25d6362be653140bfe079ab5925 /llvm/lib/Analysis/LibCallSemantics.cpp | |
parent | 58e985c2db3045f1416520212108f93c8c257b18 (diff) | |
download | bcm5719-llvm-96d011315aa01de179897eaf4e7baeddc5de1cda.tar.gz bcm5719-llvm-96d011315aa01de179897eaf4e7baeddc5de1cda.zip |
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.
llvm-svn: 228782
Diffstat (limited to 'llvm/lib/Analysis/LibCallSemantics.cpp')
-rw-r--r-- | llvm/lib/Analysis/LibCallSemantics.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/LibCallSemantics.cpp b/llvm/lib/Analysis/LibCallSemantics.cpp index 3a345c45d07..6c2ebdb4594 100644 --- a/llvm/lib/Analysis/LibCallSemantics.cpp +++ b/llvm/lib/Analysis/LibCallSemantics.cpp @@ -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); +} |