diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2011-10-05 20:05:13 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2011-10-05 20:05:13 +0000 |
commit | 79d0c4f4b098bf27a16e8071b2b981fc30d34200 (patch) | |
tree | cb9662e125abef5819853033c913524d072395cc /llvm/lib/VMCore/Function.cpp | |
parent | e37e0301372667edae46092b5bef93a6cd3e0e3a (diff) | |
download | bcm5719-llvm-79d0c4f4b098bf27a16e8071b2b981fc30d34200.tar.gz bcm5719-llvm-79d0c4f4b098bf27a16e8071b2b981fc30d34200.zip |
Check for the returns_twice attribute in callsFunctionThatReturnsTwice. This
fixes PR11038, but there are still some cleanups to be done.
llvm-svn: 141204
Diffstat (limited to 'llvm/lib/VMCore/Function.cpp')
-rw-r--r-- | llvm/lib/VMCore/Function.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/llvm/lib/VMCore/Function.cpp b/llvm/lib/VMCore/Function.cpp index 1f59bf97167..ef0827b110e 100644 --- a/llvm/lib/VMCore/Function.cpp +++ b/llvm/lib/VMCore/Function.cpp @@ -17,6 +17,7 @@ #include "llvm/LLVMContext.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/CallSite.h" +#include "llvm/Support/InstIterator.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/StringPool.h" @@ -416,7 +417,6 @@ bool Function::hasAddressTaken(const User* *PutOffender) const { /// FIXME: Remove after <rdar://problem/8031714> is fixed. /// FIXME: Is the above FIXME valid? bool Function::callsFunctionThatReturnsTwice() const { - const Module *M = this->getParent(); static const char *ReturnsTwiceFns[] = { "_setjmp", "setjmp", @@ -428,16 +428,25 @@ bool Function::callsFunctionThatReturnsTwice() const { "getcontext" }; - for (unsigned I = 0; I < array_lengthof(ReturnsTwiceFns); ++I) - if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) { - if (!Callee->use_empty()) - for (Value::const_use_iterator - I = Callee->use_begin(), E = Callee->use_end(); - I != E; ++I) - if (const CallInst *CI = dyn_cast<CallInst>(*I)) - if (CI->getParent()->getParent() == this) - return true; + for (const_inst_iterator I = inst_begin(this), E = inst_end(this); I != E; + ++I) { + const CallInst* callInst = dyn_cast<CallInst>(&*I); + if (!callInst) + continue; + if (callInst->canReturnTwice()) + return true; + + // check for known function names. + // FIXME: move this to clang. + Function *F = callInst->getCalledFunction(); + if (!F) + continue; + StringRef Name = F->getName(); + for (unsigned J = 0; J < array_lengthof(ReturnsTwiceFns); ++J) { + if (Name == ReturnsTwiceFns[J]) + return true; } + } return false; } |