diff options
author | Anna Zaks <ganna@apple.com> | 2011-11-01 22:41:19 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-11-01 22:41:19 +0000 |
commit | 6800ba622e4edf287801ac69c42c61e7e294b06b (patch) | |
tree | d04814bf89def505380d20dfdeb83ac681f72d18 | |
parent | 2d950b15b2b2b650b102ecf0c6b50b45e0cb6a8a (diff) |
[analyzer] Make sink attribute part of the node profile.
This prevents caching out on nodes with different sink flag.
(This is a cleaner fix for radar://10376675).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143517 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h | 20 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CoreEngine.cpp | 71 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 14 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 2 |
4 files changed, 50 insertions, 57 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index 0e1cae9580..f7ffd0af64 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -116,9 +116,12 @@ class ExplodedNode : public llvm::FoldingSetNode { public: - explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state) + explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state, + bool IsSink) : Location(loc), State(state) { const_cast<ProgramState*>(State)->incrementReferenceCount(); + if (IsSink) + Succs.setFlag(); } ~ExplodedNode() { @@ -149,13 +152,16 @@ public: const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); } static void Profile(llvm::FoldingSetNodeID &ID, - const ProgramPoint &Loc, const ProgramState *state) { + const ProgramPoint &Loc, + const ProgramState *state, + bool IsSink) { ID.Add(Loc); ID.AddPointer(state); + ID.AddBoolean(IsSink); } void Profile(llvm::FoldingSetNodeID& ID) const { - Profile(ID, getLocation(), getState()); + Profile(ID, getLocation(), getState(), isSink()); } /// addPredeccessor - Adds a predecessor to the current node, and @@ -168,7 +174,6 @@ public: bool pred_empty() const { return Preds.empty(); } bool isSink() const { return Succs.getFlag(); } - void markAsSink() { Succs.setFlag(); } ExplodedNode *getFirstPred() { return pred_empty() ? NULL : *(pred_begin()); @@ -271,12 +276,13 @@ protected: bool reclaimNodes; public: - /// getNode - Retrieve the node associated with a (Location,State) pair, + + /// \brief Retrieve the node associated with a (Location,State) pair, /// where the 'Location' is a ProgramPoint in the CFG. If no node for - /// this pair exists, it is created. IsNew is set to true if + /// this pair exists, it is created. IsNew is set to true if /// the node was freshly created. - ExplodedNode *getNode(const ProgramPoint &L, const ProgramState *State, + bool IsSink = false, bool* IsNew = 0); ExplodedGraph* MakeEmptyGraph() const { diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp index 0003e6cd3f..0b9371c4b5 100644 --- a/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -441,7 +441,7 @@ void CoreEngine::generateNode(const ProgramPoint &Loc, ExplodedNode *Pred) { bool IsNew; - ExplodedNode *Node = G->getNode(Loc, State, &IsNew); + ExplodedNode *Node = G->getNode(Loc, State, false, &IsNew); if (Pred) Node->addPredecessor(Pred, *G); // Link 'Node' with its predecessor. @@ -485,7 +485,7 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, } bool IsNew; - ExplodedNode *Succ = G->getNode(Loc, N->getState(), &IsNew); + ExplodedNode *Succ = G->getNode(Loc, N->getState(), false, &IsNew); Succ->addPredecessor(N, *G); if (IsNew) @@ -502,7 +502,7 @@ ExplodedNode *CoreEngine::generateCallExitNode(ExplodedNode *N) { CallExit Loc(CE, LocCtx); bool isNew; - ExplodedNode *Node = G->getNode(Loc, N->getState(), &isNew); + ExplodedNode *Node = G->getNode(Loc, N->getState(), false, &isNew); Node->addPredecessor(N, *G); return isNew ? Node : 0; } @@ -543,17 +543,14 @@ ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc, bool MarkAsSink) { HasGeneratedNodes = true; bool IsNew; - ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew); + ExplodedNode *N = C.Eng.G->getNode(Loc, State, MarkAsSink, &IsNew); N->addPredecessor(FromN, *C.Eng.G); Frontier.erase(FromN); - assert(IsNew || N->isSink() == MarkAsSink); if (!IsNew) return 0; - if (MarkAsSink) - N->markAsSink(); - else + if (!MarkAsSink) Frontier.Add(N); return N; @@ -582,25 +579,20 @@ ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State, ExplodedNode* IndirectGotoNodeBuilder::generateNode(const iterator &I, const ProgramState *St, - bool isSink) { + bool IsSink) { bool IsNew; - ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(), - Pred->getLocationContext()), St, &IsNew); - + Pred->getLocationContext()), St, + IsSink, &IsNew); Succ->addPredecessor(Pred, *Eng.G); - if (IsNew) { - - if (isSink) - Succ->markAsSink(); - else - Eng.WList->enqueue(Succ); + if (!IsNew) + return 0; - return Succ; - } + if (!IsSink) + Eng.WList->enqueue(Succ); - return NULL; + return Succ; } @@ -610,20 +602,20 @@ SwitchNodeBuilder::generateCaseStmtNode(const iterator &I, bool IsNew; ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(), - Pred->getLocationContext()), - St, &IsNew); + Pred->getLocationContext()), St, + false, &IsNew); Succ->addPredecessor(Pred, *Eng.G); - if (IsNew) { - Eng.WList->enqueue(Succ); - return Succ; - } - return NULL; + if (!IsNew) + return 0; + + Eng.WList->enqueue(Succ); + return Succ; } ExplodedNode* SwitchNodeBuilder::generateDefaultCaseNode(const ProgramState *St, - bool isSink) { + bool IsSink) { // Get the block for the default case. assert(Src->succ_rbegin() != Src->succ_rend()); CFGBlock *DefaultBlock = *Src->succ_rbegin(); @@ -634,21 +626,18 @@ SwitchNodeBuilder::generateDefaultCaseNode(const ProgramState *St, return NULL; bool IsNew; - ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock, - Pred->getLocationContext()), St, &IsNew); + Pred->getLocationContext()), St, + IsSink, &IsNew); Succ->addPredecessor(Pred, *Eng.G); - if (IsNew) { - if (isSink) - Succ->markAsSink(); - else - Eng.WList->enqueue(Succ); + if (!IsNew) + return 0; - return Succ; - } + if (!IsSink) + Eng.WList->enqueue(Succ); - return NULL; + return Succ; } void CallEnterNodeBuilder::generateNode(const ProgramState *state) { @@ -706,7 +695,7 @@ void CallEnterNodeBuilder::generateNode(const ProgramState *state) { BlockEdge Loc(Entry, SuccB, CalleeCtx); bool isNew; - ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew); + ExplodedNode *Node = Eng.G->getNode(Loc, state, false, &isNew); Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G); if (isNew) @@ -721,7 +710,7 @@ void CallExitNodeBuilder::generateNode(const ProgramState *state) { // that triggers the dtor. PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent()); bool isNew; - ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew); + ExplodedNode *Node = Eng.G->getNode(Loc, state, false, &isNew); Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G); if (isNew) Eng.WList->enqueue(Node, LocCtx->getCallSiteBlock(), diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index 5762a21600..7edcb752f7 100644 --- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -215,12 +215,14 @@ ExplodedNode** ExplodedNode::NodeGroup::end() const { } ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L, - const ProgramState *State, bool* IsNew) { + const ProgramState *State, + bool IsSink, + bool* IsNew) { // Profile 'State' to determine if we already have an existing node. llvm::FoldingSetNodeID profile; void *InsertPos = 0; - NodeTy::Profile(profile, L, State); + NodeTy::Profile(profile, L, State, IsSink); NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos); if (!V) { @@ -234,7 +236,7 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L, V = (NodeTy*) getAllocator().Allocate<NodeTy>(); } - new (V) NodeTy(L, State); + new (V) NodeTy(L, State, IsSink); if (reclaimNodes) { if (!recentlyAllocatedNodes) @@ -334,7 +336,7 @@ ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources, // Create the corresponding node in the new graph and record the mapping // from the old node to the new node. - ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, NULL); + ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, N->isSink(), 0); Pass2[N] = NewN; // Also record the reverse mapping from the new node to the old node. @@ -372,10 +374,6 @@ ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources, if (Pass1.count(*I)) WL2.push_back(*I); } - - // Finally, explicitly mark all nodes without any successors as sinks. - if (N->isSink()) - NewN->markAsSink(); } return G; diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 9973b7765c..471936c84a 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1595,7 +1595,7 @@ ExprEngine::getEagerlyAssumeTags() { } void ExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, - const Expr *Ex) { + const Expr *Ex) { StmtNodeBuilder Bldr(Src, Dst, *currentBuilderContext); for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { |