Don't segfault on mutual recursion, as pointed out by Frits.
authorAnders Carlsson <andersca@mac.com>
Sun, 20 Mar 2011 20:16:43 +0000 (20:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 20 Mar 2011 20:16:43 +0000 (20:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127975 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/GlobalOpt.cpp

index 12753cdaf19a8214a5a7c65ee0207e92fa889d53..1a8b944363f70848df0119f7064d3ee96efa19e1 100644 (file)
@@ -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.