From cf118d41f7930a18dce97416ef7834a62642f587 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 4 Feb 2009 23:49:09 +0000 Subject: Overhaul BugReporter interface and implementation. The new interface cleans up the ownership of BugTypes and BugReports. Now BugReports are owned by BugTypes, and BugTypes are owned by the BugReporter object. The major functionality change in this patch is that reports are not immediately emitted by a call to BugReporter::EmitWarning (now called EmitReport), but instead of queued up in report "equivalence classes". When BugReporter::FlushReports() is called, it emits one diagnostic per report equivalence class. This provides a nice cleanup with the caching of reports as well as enables the BugReporter engine to select the "best" path for reporting a path-sensitive bug based on all the locations in the ExplodedGraph that the same bug could occur. Along with this patch, Leaks are now coalesced into a common equivalence class by their allocation site, and the "summary" diagnostic for leaks now reports the allocation site as the location of the bug (this may later be augmented to also provide an example location where the leak occurs). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63796 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ExplodedGraph.cpp | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'lib/Analysis/ExplodedGraph.cpp') diff --git a/lib/Analysis/ExplodedGraph.cpp b/lib/Analysis/ExplodedGraph.cpp index 4e41b60da3..864a83b884 100644 --- a/lib/Analysis/ExplodedGraph.cpp +++ b/lib/Analysis/ExplodedGraph.cpp @@ -122,13 +122,17 @@ ExplodedNodeImpl::NodeGroup::~NodeGroup() { ExplodedGraphImpl* ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources, - const ExplodedNodeImpl* const* EndSources) const{ - - typedef llvm::DenseMap Pass1Ty; - typedef llvm::DenseMap Pass2Ty; + const ExplodedNodeImpl* const* EndSources, + InterExplodedGraphMapImpl* M) const { + typedef llvm::DenseMap Pass1Ty; Pass1Ty Pass1; - Pass2Ty Pass2; + + typedef llvm::DenseMap Pass2Ty; + + Pass2Ty& Pass2 = M->M; llvm::SmallVector WL2; @@ -139,23 +143,28 @@ ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources, std::list > WL1, WL1_Loops; - for (const ExplodedNodeImpl* const* I = BeginSources; I != EndSources; ++I) + for (const ExplodedNodeImpl* const* I = BeginSources; I != EndSources; ++I){ + assert(*I); WL1.push_back(std::make_pair(*I, *I)); + } // Process the worklist. - while (! (WL1.empty() && WL1_Loops.empty())) { + while (!WL1.empty() || !WL1_Loops.empty()) { // Only dequeue from the "loops" worklist if WL1 has no items. // Thus we prioritize for paths that don't span loop boundaries. - const ExplodedNodeImpl *N, *Src; + const ExplodedNodeImpl *N = 0, *Src = 0; if (WL1.empty()) { + assert(!WL1_Loops.empty()); N = WL1_Loops.back().first; + assert(N); Src = WL1_Loops.back().second; WL1_Loops.pop_back(); } else { N = WL1.back().first; + assert(N); Src = WL1.back().second; WL1.pop_back(); } @@ -207,19 +216,21 @@ ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources, case Stmt::ForStmtClass: case Stmt::WhileStmtClass: case Stmt::DoStmtClass: + assert(*I); WL1_Loops.push_front(std::make_pair(*I, Src)); continue; } + assert(*I); WL1.push_front(std::make_pair(*I, Src)); } } } if (WL2.empty()) - return NULL; - + return 0; + ExplodedGraphImpl* G = MakeEmptyGraph(); // ===- Pass 2 (forward DFS to construct the new graph) -=== @@ -285,3 +296,14 @@ ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources, return G; } + +ExplodedNodeImpl* +InterExplodedGraphMapImpl::getMappedImplNode(const ExplodedNodeImpl* N) const { + llvm::DenseMap::iterator I = + M.find(N); + + return I == M.end() ? 0 : I->second; +} + +InterExplodedGraphMapImpl::InterExplodedGraphMapImpl() {} + -- cgit v1.2.3-70-g09d2