diff options
author | Anders Carlsson <andersca@mac.com> | 2011-03-20 20:16:43 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-03-20 20:16:43 +0000 |
commit | fcec2f519a1582b5177e36b7faf8ca76a06d14b4 (patch) | |
tree | b532dae43eef0d9bc1bb6e73f436e23e122f1028 /llvm/lib | |
parent | 48a44911d35edebcba493555a5f30082ee97761c (diff) | |
download | bcm5719-llvm-fcec2f519a1582b5177e36b7faf8ca76a06d14b4.tar.gz bcm5719-llvm-fcec2f519a1582b5177e36b7faf8ca76a06d14b4.zip |
Don't segfault on mutual recursion, as pointed out by Frits.
llvm-svn: 127975
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/IPO/GlobalOpt.cpp | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 12753cdaf19..1a8b944363f 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -2723,7 +2723,8 @@ static Function *FindCXAAtExit(Module &M) { /// Note that we assume that other optimization passes have already simplified /// the code so we only look for a function with a single basic block, where /// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. -static bool cxxDtorIsEmpty(const Function& Fn) { +static bool cxxDtorIsEmpty(const Function &Fn, + SmallPtrSet<const Function *, 8> &CalledFunctions) { // FIXME: We could eliminate C++ destructors if they're readonly/readnone and // unwind, but that doesn't seem worth doing. if (Fn.isDeclaration()) @@ -2742,10 +2743,10 @@ static bool cxxDtorIsEmpty(const Function& Fn) { return false; // Don't treat recursive functions as empty. - if (CalledFn == &Fn) + if (!CalledFunctions.insert(CalledFn)) return false; - if (!cxxDtorIsEmpty(*CalledFn)) + if (!cxxDtorIsEmpty(*CalledFn, CalledFunctions)) return false; } else if (isa<ReturnInst>(*I)) return true; @@ -2784,7 +2785,8 @@ bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { if (!DtorFn) continue; - if (!cxxDtorIsEmpty(*DtorFn)) + SmallPtrSet<const Function *, 8> CalledFunctions; + if (!cxxDtorIsEmpty(*DtorFn, CalledFunctions)) continue; // Just remove the call. |