make CallGraphNode dtor abort if a node is deleted when there are still
authorChris Lattner <sabre@nondot.org>
Tue, 20 Apr 2010 00:47:34 +0000 (00:47 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 20 Apr 2010 00:47:34 +0000 (00:47 +0000)
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
lib/Analysis/IPA/CallGraph.cpp

index 287fe4faa4f560a397c7637079ec0c72cfb5fb21..a4884edd5bd6b42328d3e5be2bce938ec01026ff 100644 (file)
@@ -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;
+  }
 };
 
 //===----------------------------------------------------------------------===//
index 8c43aa14885d0c3d39b2352e72c6d0a1fd06957f..c59c31c22a936218fd23ddf878b25a7e6d411b90 100644 (file)
@@ -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;