From 8a39ed75ec57c7fabde318c0d45fac014ac287f4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 20 Apr 2010 00:47:34 +0000 Subject: [PATCH] make CallGraphNode dtor abort if a node is deleted when there are still references to it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101847 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/CallGraph.h | 8 ++++++++ lib/Analysis/IPA/CallGraph.cpp | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 287fe4faa4f..a4884edd5bd 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -187,6 +187,9 @@ public: // CallGraphNode ctor - Create a node for the specified function. inline CallGraphNode(Function *f) : F(f), NumReferences(0) {} + ~CallGraphNode() { + assert(NumReferences == 0 && "Node deleted while references remain"); + } //===--------------------------------------------------------------------- // Accessor methods. @@ -277,6 +280,11 @@ public: /// time, so it should be used sparingly. void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode); + /// allReferencesDropped - This is a special function that should only be + /// used by the CallGraph class. + void allReferencesDropped() { + NumReferences = 0; + } }; //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp index 8c43aa14885..c59c31c22a9 100644 --- a/lib/Analysis/IPA/CallGraph.cpp +++ b/lib/Analysis/IPA/CallGraph.cpp @@ -158,6 +158,7 @@ private: // destroy - Release memory for the call graph virtual void destroy() { /// CallsExternalNode is not in the function map, delete it explicitly. + CallsExternalNode->allReferencesDropped(); delete CallsExternalNode; CallsExternalNode = 0; CallGraph::destroy(); @@ -181,6 +182,14 @@ void CallGraph::initialize(Module &M) { void CallGraph::destroy() { if (FunctionMap.empty()) return; + // Reset all node's use counts to zero before deleting them to prevent an + // assertion from firing. +#ifndef NDEBUG + for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end(); + I != E; ++I) + I->second->allReferencesDropped(); +#endif + for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end(); I != E; ++I) delete I->second;