diff options
-rw-r--r-- | clang/Analysis/ExplodedGraph.cpp | 59 | ||||
-rw-r--r-- | clang/Analysis/GRExprEngine.cpp | 42 | ||||
-rw-r--r-- | clang/Analysis/GRSimpleVals.cpp | 2 |
3 files changed, 81 insertions, 22 deletions
diff --git a/clang/Analysis/ExplodedGraph.cpp b/clang/Analysis/ExplodedGraph.cpp index 421b9e3846b..2ba46d77d63 100644 --- a/clang/Analysis/ExplodedGraph.cpp +++ b/clang/Analysis/ExplodedGraph.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include <vector> +#include <list> using namespace clang; @@ -89,7 +90,7 @@ ExplodedNodeImpl::NodeGroup::~NodeGroup() { ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, ExplodedNodeImpl** EndSources) const{ - typedef llvm::DenseSet<ExplodedNodeImpl*> Pass1Ty; + typedef llvm::DenseMap<ExplodedNodeImpl*, ExplodedNodeImpl*> Pass1Ty; typedef llvm::DenseMap<ExplodedNodeImpl*, ExplodedNodeImpl*> Pass2Ty; Pass1Ty Pass1; @@ -101,30 +102,58 @@ ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, // Enqueue the source nodes to the first worklist. - llvm::SmallVector<ExplodedNodeImpl*, 10> WL1; + std::list<std::pair<ExplodedNodeImpl*, ExplodedNodeImpl*> > WL1; for (ExplodedNodeImpl** I = BeginSources; I != EndSources; ++I) - WL1.push_back(*I); + WL1.push_back(std::make_pair(*I, *I)); // Process the worklist. while (!WL1.empty()) { - ExplodedNodeImpl* N = WL1.back(); + ExplodedNodeImpl* N = WL1.back().first; + ExplodedNodeImpl* Src = WL1.back().second; + WL1.pop_back(); - if (Pass1.count(N)) + if (Pass1.find(N) != Pass1.end()) continue; - Pass1.insert(N); + bool PredHasSameSource = false; + bool VisitPreds = true; + + for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end(); + I!=E; ++I) { + + Pass1Ty::iterator pi = Pass1.find(*I); + + if (pi == Pass1.end()) + continue; + + VisitPreds = false; + + if (pi->second == Src) { + PredHasSameSource = true; + break; + } + } + + if (VisitPreds || !PredHasSameSource) { + + Pass1[N] = Src; - if (N->Preds.empty()) { - WL2.push_back(N); - continue; + if (N->Preds.empty()) { + WL2.push_back(N); + continue; + } } + else + Pass1[N] = NULL; - for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I) - WL1.push_back(*I); + if (VisitPreds) + for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end(); + I!=E; ++I) + WL1.push_front(std::make_pair(*I, Src)); } } @@ -182,8 +211,12 @@ ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, // Enqueue nodes to the worklist that were marked during pass 1. - if (Pass1.count(*I)) - WL2.push_back(*I); + Pass1Ty::iterator pi = Pass1.find(*I); + + if (pi == Pass1.end() || pi->second == NULL) + continue; + + WL2.push_back(*I); } if (N->isSink()) diff --git a/clang/Analysis/GRExprEngine.cpp b/clang/Analysis/GRExprEngine.cpp index e2fec9f88f5..61643a440ef 100644 --- a/clang/Analysis/GRExprEngine.cpp +++ b/clang/Analysis/GRExprEngine.cpp @@ -1805,23 +1805,49 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> : #endif #ifndef NDEBUG + +template <typename ITERATOR> +GRExprEngine::NodeTy* GetGraphNode(ITERATOR I) { return *I; } + +template <> +GRExprEngine::NodeTy* +GetGraphNode<llvm::DenseMap<GRExprEngine::NodeTy*, Expr*>::iterator> + (llvm::DenseMap<GRExprEngine::NodeTy*, Expr*>::iterator I) { + return I->first; +} + template <typename ITERATOR> static void AddSources(llvm::SmallVector<GRExprEngine::NodeTy*, 10>& Sources, - ITERATOR I, ITERATOR E) { + ITERATOR I, ITERATOR E) { + + llvm::SmallPtrSet<void*,10> CachedSources; - for ( ; I != E; ++I ) - Sources.push_back(*I); + for ( ; I != E; ++I ) { + GRExprEngine::NodeTy* N = GetGraphNode(I); + void* p = N->getLocation().getRawData(); + + if (CachedSources.count(p)) + continue; + + CachedSources.insert(p); + + Sources.push_back(N); + } } #endif void GRExprEngine::ViewGraph(bool trim) { #ifndef NDEBUG if (trim) { - llvm::SmallVector<NodeTy*, 10> Sources; - AddSources(Sources, null_derefs_begin(), null_derefs_end()); - AddSources(Sources, undef_derefs_begin(), undef_derefs_end()); - - ViewGraph(&Sources[0], &Sources[0]+Sources.size()); + llvm::SmallVector<NodeTy*, 10> Src; + AddSources(Src, null_derefs_begin(), null_derefs_end()); + AddSources(Src, undef_derefs_begin(), undef_derefs_end()); + AddSources(Src, explicit_bad_divides_begin(), explicit_bad_divides_end()); + AddSources(Src, undef_results_begin(), undef_results_end()); + AddSources(Src, bad_calls_begin(), bad_calls_end()); + AddSources(Src, undef_arg_begin(), undef_arg_end()); + + ViewGraph(&Src[0], &Src[0]+Src.size()); } else { GraphPrintCheckerState = this; diff --git a/clang/Analysis/GRSimpleVals.cpp b/clang/Analysis/GRSimpleVals.cpp index 16cd6747a01..75ca27e1b4b 100644 --- a/clang/Analysis/GRSimpleVals.cpp +++ b/clang/Analysis/GRSimpleVals.cpp @@ -101,7 +101,7 @@ unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx, CheckerState->setTransferFunctions(GRSV); // Execute the worklist algorithm. - Eng.ExecuteWorkList(50000); + Eng.ExecuteWorkList(100000); SourceManager& SrcMgr = Ctx.getSourceManager(); |