aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-03-20 20:16:43 +0000
committerAnders Carlsson <andersca@mac.com>2011-03-20 20:16:43 +0000
commit372ec6aa915534f3b11c252dbc9e6c63814bcab3 (patch)
tree48b8d97c2d2efbfed8638732f1d5c3ea2434ae13 /lib/Transforms
parent1f7c7ba380cf411fd02a070822c439fadac91ce6 (diff)
Don't segfault on mutual recursion, as pointed out by Frits.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127975 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 12753cdaf1..1a8b944363 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/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.