diff options
author | Anna Zaks <ganna@apple.com> | 2011-10-18 23:06:44 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-10-18 23:06:44 +0000 |
commit | 4e82d3cf6fd4c907265e3fa3aac0a835c35dc759 (patch) | |
tree | f997ce150d184ef26d497440adaaf6dbbbaa33c0 /include/clang/StaticAnalyzer/Core | |
parent | 3152b3cb5b6a2f797d0972c81a5eb3fd69c0d620 (diff) |
[analyzer] Make NodeBuilder and Pred node loosely coupled
NodeBuilder should not assume it's dealing with a single predecessor. Remove predecessor getters. Modify the BranchNodeBuilder to not be responsible for doing auto-transitions (which depend on a predecessor).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/StaticAnalyzer/Core')
5 files changed, 32 insertions, 42 deletions
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 51533489e5..2e270000c7 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -215,8 +215,9 @@ public: class BranchCondition { template <typename CHECKER> static void _checkBranchCondition(void *checker, const Stmt *condition, - NodeBuilder &B, ExprEngine &Eng) { - ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng); + NodeBuilder &B, ExplodedNode *Pred, + ExprEngine &Eng) { + ((const CHECKER *)checker)->checkBranchCondition(condition, B, Pred, Eng); } public: diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 6026aec643..7450df63c4 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -232,7 +232,8 @@ public: /// \brief Run checkers for branch condition. void runCheckersForBranchCondition(const Stmt *condition, - NodeBuilder &B, ExprEngine &Eng); + NodeBuilder &B, ExplodedNode *Pred, + ExprEngine &Eng); /// \brief Run checkers for live symbols. /// @@ -334,7 +335,8 @@ public: typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)> CheckEndPathFunc; - typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExprEngine &)> + typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExplodedNode *Pred, + ExprEngine &)> CheckBranchConditionFunc; typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 7d7aa1417b..4892293a42 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -191,6 +191,8 @@ protected: /// is set to false, autotransitions are yet to be generated. bool Finalized; + bool HasGeneratedNodes; + /// \brief The frontier set - a set of nodes which need to be propagated after /// the builder dies. typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy; @@ -218,14 +220,14 @@ protected: public: NodeBuilder(ExplodedNode *N, NodeBuilderContext &Ctx, bool F = true) - : BuilderPred(N), C(Ctx), Finalized(F) { + : BuilderPred(N), C(Ctx), Finalized(F), HasGeneratedNodes(false) { assert(!N->isSink()); Deferred.insert(N); } /// Create a new builder using the parent builder's context. NodeBuilder(ExplodedNode *N, const NodeBuilder &ParentBldr, bool F = true) - : BuilderPred(N), C(ParentBldr.C), Finalized(F) { + : BuilderPred(N), C(ParentBldr.C), Finalized(F), HasGeneratedNodes(false) { assert(!N->isSink()); Deferred.insert(N); } @@ -243,8 +245,9 @@ public: return generateNodeImpl(PP, State, Pred, MarkAsSink); } + // TODO: will get removed. bool hasGeneratedNodes() const { - return (!Deferred.count(BuilderPred)); + return HasGeneratedNodes; } typedef DeferredTy::iterator iterator; @@ -269,12 +272,6 @@ public: BuilderPred->getLocationContext()->getCurrentStackFrame(), C.Block->getBlockID()); } - - // \brief Get the builder's predecessor - the parent to all the other nodes. - ExplodedNode *getPredecessor() const { return BuilderPred; } - - // \brief Returns state of the predecessor. - const ProgramState *getState() const { return BuilderPred->getState(); } }; class CommonNodeBuilder { @@ -366,7 +363,7 @@ public: } void importNodesFromBuilder(const NodeBuilder &NB) { - ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.getPredecessor()); + ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.BuilderPred); if (NB.hasGeneratedNodes()) { Deferred.erase(NBPred); Deferred.insert(NB.Deferred.begin(), NB.Deferred.end()); @@ -378,35 +375,20 @@ class BranchNodeBuilder: public NodeBuilder { const CFGBlock *DstT; const CFGBlock *DstF; - bool GeneratedTrue; - bool GeneratedFalse; bool InFeasibleTrue; bool InFeasibleFalse; - /// Generate default branching transitions of none were generated or - /// suppressed. - void finalizeResults() { - if (Finalized) - return; - if (!GeneratedTrue) generateNode(BuilderPred->State, true); - if (!GeneratedFalse) generateNode(BuilderPred->State, false); - Finalized = true; - } - public: BranchNodeBuilder(ExplodedNode *Pred, NodeBuilderContext &C, const CFGBlock *dstT, const CFGBlock *dstF) - : NodeBuilder(Pred, C, false), DstT(dstT), DstF(dstF), - GeneratedTrue(false), GeneratedFalse(false), - InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) { - } + : NodeBuilder(Pred, C), DstT(dstT), DstF(dstF), + InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} /// Create a new builder using the parent builder's context. BranchNodeBuilder(ExplodedNode *Pred, BranchNodeBuilder &ParentBldr) - : NodeBuilder(Pred, ParentBldr, false), DstT(ParentBldr.DstT), - DstF(ParentBldr.DstF), GeneratedTrue(false), GeneratedFalse(false), - InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) { - } + : NodeBuilder(Pred, ParentBldr), DstT(ParentBldr.DstT), + DstF(ParentBldr.DstF), + InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} ExplodedNode *generateNode(const ProgramState *State, bool branch, ExplodedNode *Pred = 0); @@ -417,9 +399,9 @@ public: void markInfeasible(bool branch) { if (branch) - InFeasibleTrue = GeneratedTrue = true; + InFeasibleTrue = true; else - InFeasibleFalse = GeneratedFalse = true; + InFeasibleFalse = true; } bool isFeasible(bool branch) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index bc84e2f7d5..df4580aa90 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -132,16 +132,20 @@ public: /// processCFGElement - Called by CoreEngine. Used to generate new successor /// nodes by processing the 'effects' of a CFG element. - void processCFGElement(const CFGElement E, StmtNodeBuilder& builder); + void processCFGElement(const CFGElement E, StmtNodeBuilder& Bldr, + ExplodedNode *Pred); - void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder); + void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder, + ExplodedNode *Pred); - void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &builder); + void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &Bldr, + ExplodedNode *Pred); - void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder); + void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder, + ExplodedNode *Pred); void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, - StmtNodeBuilder &builder); + StmtNodeBuilder &builder, ExplodedNode *Pred); void ProcessBaseDtor(const CFGBaseDtor D, StmtNodeBuilder &builder); void ProcessMemberDtor(const CFGMemberDtor D, StmtNodeBuilder &builder); void ProcessTemporaryDtor(const CFGTemporaryDtor D, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index 38b7538b6b..8dfc1865bd 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -55,7 +55,8 @@ public: /// Called by CoreEngine. Used to generate new successor /// nodes by processing the 'effects' of a block-level statement. - virtual void processCFGElement(const CFGElement E, StmtNodeBuilder& builder)=0; + virtual void processCFGElement(const CFGElement E, StmtNodeBuilder& builder, + ExplodedNode* Pred)=0; /// Called by CoreEngine when it starts processing a CFGBlock. The /// SubEngine is expected to populate dstNodes with new nodes representing |