From 88d9462b734009bacc292e9854bfe86d6123ebf9 Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Tue, 18 Oct 2011 23:06:33 +0000 Subject: [PATCH] [analyzer] Subclassing StmtBuilder from the NodeBuilder llvm-svn: 142451 --- .../Core/PathSensitive/CheckerContext.h | 2 +- .../Core/PathSensitive/CoreEngine.h | 61 +++++----------- clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 71 +++++-------------- .../StaticAnalyzer/Core/ExprEngineObjC.cpp | 2 +- 4 files changed, 38 insertions(+), 98 deletions(-) diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 1bbc66ced708..1d0d716944e4 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -50,7 +50,7 @@ public: Location(loc), ST(st), size(Dst.size()), - Ctx(builder.Eng, builder.getBlock()), + Ctx(builder.C.Eng, builder.getBlock()), NB(pred, Ctx), respondsToCallback(respondsToCB) { assert(!(ST && ST != Pred->getState())); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 8433f4cd2832..6e9f54fca768 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -181,7 +181,12 @@ protected: friend class StmtNodeBuilder; ExplodedNode *BuilderPred; + +// TODO: Context should become protected after refactoring is done. +public: const NodeBuilderContext &C; +protected: + bool Finalized; /// \brief The frontier set - a set of nodes which need to be propagated after @@ -254,6 +259,9 @@ public: return Deferred.end(); } + /// \brief Return the CFGBlock associated with this builder. + const CFGBlock *getBlock() const { return C.Block; } + /// \brief Returns the number of times the current basic block has been /// visited on the exploded graph path. unsigned getCurrentBlockCount() const { @@ -272,8 +280,6 @@ public: class CommonNodeBuilder { protected: ExplodedNode *Pred; -public: - // TODO: make protected. CoreEngine& Eng; CommonNodeBuilder(CoreEngine* E, ExplodedNode *P) : Pred(P), Eng(*E) {} @@ -281,49 +287,36 @@ public: }; -class StmtNodeBuilder: public CommonNodeBuilder { - const CFGBlock &B; +class StmtNodeBuilder: public NodeBuilder { const unsigned Idx; public: bool PurgingDeadSymbols; bool BuildSinks; + // TODO: Remove the flag. We should be able to use the method in the parent. bool hasGeneratedNode; ProgramPoint::Kind PointKind; const ProgramPointTag *Tag; - typedef llvm::SmallPtrSet DeferredTy; - DeferredTy Deferred; - void GenerateAutoTransition(ExplodedNode *N); public: - StmtNodeBuilder(const CFGBlock *b, - unsigned idx, - ExplodedNode *N, - CoreEngine* e); + StmtNodeBuilder(ExplodedNode *N, unsigned idx, NodeBuilderContext &Ctx); ~StmtNodeBuilder(); - - ExplodedNode *getPredecessor() const { return Pred; } - unsigned getCurrentBlockCount() const { - return getBlockCounter().getNumVisited( - Pred->getLocationContext()->getCurrentStackFrame(), - B.getBlockID()); - } - ExplodedNode *generateNode(const Stmt *S, const ProgramState *St, ExplodedNode *Pred, ProgramPoint::Kind K, - const ProgramPointTag *tag = 0) { - hasGeneratedNode = true; - + const ProgramPointTag *tag = 0, + bool MarkAsSink = false) { if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind; - return generateNodeInternal(S, St, Pred, K, tag ? tag : Tag); + const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, + Pred->getLocationContext(), tag ? tag : Tag); + return generateNodeImpl(L, St, Pred, MarkAsSink); } ExplodedNode *generateNode(const Stmt *S, @@ -336,33 +329,16 @@ public: ExplodedNode *generateNode(const ProgramPoint &PP, const ProgramState *State, ExplodedNode *Pred) { - hasGeneratedNode = true; - return generateNodeInternal(PP, State, Pred); + return generateNodeImpl(PP, State, Pred, false); } - ExplodedNode* - generateNodeInternal(const ProgramPoint &PP, - const ProgramState *State, - ExplodedNode *Pred); - - ExplodedNode* - generateNodeInternal(const Stmt *S, - const ProgramState *State, - ExplodedNode *Pred, - ProgramPoint::Kind K, - const ProgramPointTag *tag = 0); - /// getStmt - Return the current block-level expression associated with /// this builder. const Stmt *getStmt() const { - const CFGStmt *CS = B[Idx].getAs(); + const CFGStmt *CS = (*C.Block)[Idx].getAs(); return CS ? CS->getStmt() : 0; } - /// getBlock - Return the CFGBlock associated with the block-level expression - /// of this builder. - const CFGBlock *getBlock() const { return &B; } - unsigned getIndex() const { return Idx; } ExplodedNode *MakeNode(ExplodedNodeSet &Dst, @@ -394,7 +370,6 @@ public: if (NB.hasGeneratedNodes()) { Deferred.erase(NBPred); Deferred.insert(NB.Deferred.begin(), NB.Deferred.end()); - hasGeneratedNode = true; } } }; diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 91aa9a567c98..fda7bbdf4c6a 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -314,7 +314,8 @@ void CoreEngine::HandleBlockEntrance(const BlockEntrance &L, // Process the entrance of the block. if (CFGElement E = L.getFirstElement()) { - StmtNodeBuilder Builder(L.getBlock(), 0, Pred, this); + NodeBuilderContext Ctx(*this, L.getBlock()); + StmtNodeBuilder Builder(Pred, 0, Ctx); SubEng.processCFGElement(E, Builder); } else @@ -430,7 +431,8 @@ void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, if (StmtIdx == B->size()) HandleBlockExit(B, Pred); else { - StmtNodeBuilder Builder(B, StmtIdx, Pred, this); + NodeBuilderContext Ctx(*this, B); + StmtNodeBuilder Builder(Pred, StmtIdx, Ctx); SubEng.processCFGElement((*B)[StmtIdx], Builder); } } @@ -484,9 +486,9 @@ GenericNodeBuilderImpl::generateNodeImpl(const ProgramState *state, } ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc, - const ProgramState *State, - ExplodedNode *FromN, - bool MarkAsSink) { + const ProgramState *State, + ExplodedNode *FromN, + bool MarkAsSink) { assert(Finalized == false && "We cannot create new nodes after the results have been finalized."); @@ -505,11 +507,9 @@ ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc, } -StmtNodeBuilder::StmtNodeBuilder(const CFGBlock *b, - unsigned idx, - ExplodedNode *N, - CoreEngine* e) - : CommonNodeBuilder(e, N), B(*b), Idx(idx), +StmtNodeBuilder::StmtNodeBuilder(ExplodedNode *N, unsigned idx, + NodeBuilderContext &Ctx) + : NodeBuilder(N, Ctx), Idx(idx), PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false), PointKind(ProgramPoint::PostStmtKind), Tag(0) { Deferred.insert(N); @@ -528,13 +528,13 @@ void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode *N) { if (isa(N->getLocation())) { // Still use the index of the CallExpr. It's needed to create the callee // StackFrameContext. - Eng.WList->enqueue(N, &B, Idx); + C.Eng.WList->enqueue(N, C.Block, Idx); return; } // Do not create extra nodes. Move to the next CFG element. if (isa(N->getLocation())) { - Eng.WList->enqueue(N, &B, Idx+1); + C.Eng.WList->enqueue(N, C.Block, Idx+1); return; } @@ -543,16 +543,16 @@ void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode *N) { if (Loc == N->getLocation()) { // Note: 'N' should be a fresh node because otherwise it shouldn't be // a member of Deferred. - Eng.WList->enqueue(N, &B, Idx+1); + C.Eng.WList->enqueue(N, C.Block, Idx+1); return; } bool IsNew; - ExplodedNode *Succ = Eng.G->getNode(Loc, N->State, &IsNew); - Succ->addPredecessor(N, *Eng.G); + ExplodedNode *Succ = C.Eng.G->getNode(Loc, N->State, &IsNew); + Succ->addPredecessor(N, *C.Eng.G); if (IsNew) - Eng.WList->enqueue(Succ, &B, Idx+1); + C.Eng.WList->enqueue(Succ, C.Block, Idx+1); } ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst, @@ -560,48 +560,13 @@ ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst, ExplodedNode *Pred, const ProgramState *St, ProgramPoint::Kind K) { - - ExplodedNode *N = generateNode(S, St, Pred, K); - - if (N) { - if (BuildSinks) - N->markAsSink(); - else + ExplodedNode *N = generateNode(S, St, Pred, K, 0, BuildSinks); + if (N && !BuildSinks){ Dst.Add(N); } - return N; } -ExplodedNode* -StmtNodeBuilder::generateNodeInternal(const Stmt *S, - const ProgramState *state, - ExplodedNode *Pred, - ProgramPoint::Kind K, - const ProgramPointTag *tag) { - - const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, - Pred->getLocationContext(), tag); - return generateNodeInternal(L, state, Pred); -} - -ExplodedNode* -StmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc, - const ProgramState *State, - ExplodedNode *Pred) { - bool IsNew; - ExplodedNode *N = Eng.G->getNode(Loc, State, &IsNew); - N->addPredecessor(Pred, *Eng.G); - Deferred.erase(Pred); - - if (IsNew) { - Deferred.insert(N); - return N; - } - - return NULL; -} - ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State, bool branch, ExplodedNode *NodePred) { diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index e0560fdfe460..7827873e9d4a 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -226,7 +226,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg, evalObjCMessage(dstEval, msg, Pred, Pred->getState()); } - assert(Builder->BuildSinks || Builder->hasGeneratedNode); + assert(Builder->BuildSinks || Builder->hasGeneratedNodes()); } // Finally, perform the post-condition check of the ObjCMessageExpr and store