diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-06 12:48:26 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-06 12:48:26 +0000 |
commit | 031ccc0555a82afc2e8afe29e19dd57ff204e2de (patch) | |
tree | 089d9ca5c64d376bf5a4880015664039bf35e66f | |
parent | 0111f575b968e423dccae439e501225b8314b257 (diff) |
Last step of template cleanup: merge *BuilderImpl to *Builder.
Some Builders need further cleanup.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78301 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/PathSensitive/Checker.h | 10 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ExplodedGraph.h | 10 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRAuditor.h | 12 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRCoreEngine.h | 449 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 187 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h | 14 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRTransferFuncs.h | 10 | ||||
-rw-r--r-- | lib/Analysis/BasicObjCFoundationChecks.cpp | 14 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 50 | ||||
-rw-r--r-- | lib/Analysis/CheckNSError.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/GRCoreEngine.cpp | 101 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 354 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 2 |
14 files changed, 514 insertions, 707 deletions
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h index f3011cc90f..278f85c160 100644 --- a/include/clang/Analysis/PathSensitive/Checker.h +++ b/include/clang/Analysis/PathSensitive/Checker.h @@ -31,7 +31,7 @@ namespace clang { class CheckerContext { ExplodedNodeSet &Dst; - GRStmtNodeBuilder<GRState> &B; + GRStmtNodeBuilder &B; GRExprEngine &Eng; ExplodedNode *Pred; SaveAndRestore<bool> OldSink; @@ -41,7 +41,7 @@ class CheckerContext { public: CheckerContext(ExplodedNodeSet &dst, - GRStmtNodeBuilder<GRState> &builder, + GRStmtNodeBuilder &builder, GRExprEngine &eng, ExplodedNode *pred, const void *tag, bool preVisit) @@ -63,7 +63,7 @@ public: return Eng.getConstraintManager(); } ExplodedNodeSet &getNodeSet() { return Dst; } - GRStmtNodeBuilder<GRState> &getNodeBuilder() { return B; } + GRStmtNodeBuilder &getNodeBuilder() { return B; } ExplodedNode *&getPredecessor() { return Pred; } const GRState *getState() { return B.GetState(Pred); } @@ -86,10 +86,10 @@ private: friend class GRExprEngine; void GR_Visit(ExplodedNodeSet &Dst, - GRStmtNodeBuilder<GRState> &Builder, + GRStmtNodeBuilder &Builder, GRExprEngine &Eng, const Stmt *stmt, - ExplodedNode *Pred, bool isPrevisit) { + ExplodedNode *Pred, bool isPrevisit) { CheckerContext C(Dst, Builder, Eng, Pred, getTag(), isPrevisit); assert(isPrevisit && "Only previsit supported for now."); _PreVisit(C, stmt); diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h index d5e3586a24..21311d1a8a 100644 --- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h +++ b/include/clang/Analysis/PathSensitive/ExplodedGraph.h @@ -50,11 +50,11 @@ class ExplodedNode : public llvm::FoldingSetNode { protected: friend class ExplodedGraph; friend class GRCoreEngine; - friend class GRStmtNodeBuilderImpl; - friend class GRBranchNodeBuilderImpl; - friend class GRIndirectGotoNodeBuilderImpl; - friend class GRSwitchNodeBuilderImpl; - friend class GREndPathNodeBuilderImpl; + friend class GRStmtNodeBuilder; + friend class GRBranchNodeBuilder; + friend class GRIndirectGotoNodeBuilder; + friend class GRSwitchNodeBuilder; + friend class GREndPathNodeBuilder; class NodeGroup { enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 }; diff --git a/include/clang/Analysis/PathSensitive/GRAuditor.h b/include/clang/Analysis/PathSensitive/GRAuditor.h index eda1985da9..6233ca8908 100644 --- a/include/clang/Analysis/PathSensitive/GRAuditor.h +++ b/include/clang/Analysis/PathSensitive/GRAuditor.h @@ -18,19 +18,15 @@ #ifndef LLVM_CLANG_ANALYSIS_GRAUDITOR #define LLVM_CLANG_ANALYSIS_GRAUDITOR -#include "clang/AST/Expr.h" -#include "clang/Analysis/PathSensitive/ExplodedGraph.h" - namespace clang { + +class ExplodedNode; +class GRStateManager; -template <typename STATE> class GRAuditor { public: - typedef ExplodedNode NodeTy; - typedef typename STATE::ManagerTy ManagerTy; - virtual ~GRAuditor() {} - virtual bool Audit(NodeTy* N, ManagerTy& M) = 0; + virtual bool Audit(ExplodedNode* N, GRStateManager& M) = 0; }; diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h index 48613d1eb8..4c04c814d9 100644 --- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -27,20 +27,14 @@ namespace clang { class GRState; class GRStateManager; - -class GRStmtNodeBuilderImpl; -template<typename STATE> class GRStmtNodeBuilder; -class GRBranchNodeBuilderImpl; -template<typename STATE> class GRBranchNodeBuilder; -class GRIndirectGotoNodeBuilderImpl; -template<typename STATE> class GRIndirectGotoNodeBuilder; -class GRSwitchNodeBuilderImpl; -template<typename STATE> class GRSwitchNodeBuilder; -class GREndPathNodeBuilderImpl; -template<typename STATE> class GREndPathNodeBuilder; - +class GRStmtNodeBuilder; +class GRBranchNodeBuilder; +class GRIndirectGotoNodeBuilder; +class GRSwitchNodeBuilder; +class GREndPathNodeBuilder; class GRWorkList; class GRCoreEngine; + //===----------------------------------------------------------------------===// /// GRCoreEngine - Implements the core logic of the graph-reachability /// analysis. It traverses the CFG and generates the ExplodedGraph. @@ -51,18 +45,11 @@ class GRCoreEngine; /// at the statement and block-level. The analyses themselves must implement /// any transfer function logic and the sub-expression level (if any). class GRCoreEngine { -public: - typedef GRState StateTy; - typedef GRStateManager StateManagerTy; - typedef ExplodedGraph GraphTy; - typedef GraphTy::NodeTy NodeTy; - -private: - friend class GRStmtNodeBuilderImpl; - friend class GRBranchNodeBuilderImpl; - friend class GRIndirectGotoNodeBuilderImpl; - friend class GRSwitchNodeBuilderImpl; - friend class GREndPathNodeBuilderImpl; + friend class GRStmtNodeBuilder; + friend class GRBranchNodeBuilder; + friend class GRIndirectGotoNodeBuilder; + friend class GRSwitchNodeBuilder; + friend class GREndPathNodeBuilder; GRSubEngine& SubEngine; @@ -96,9 +83,9 @@ private: return SubEngine.getInitialState(); } - void ProcessEndPath(GREndPathNodeBuilderImpl& BuilderImpl); + void ProcessEndPath(GREndPathNodeBuilder& Builder); - void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& BuilderImpl); + void ProcessStmt(Stmt* S, GRStmtNodeBuilder& Builder); bool ProcessBlockEntrance(CFGBlock* Blk, const GRState* State, @@ -106,13 +93,13 @@ private: void ProcessBranch(Stmt* Condition, Stmt* Terminator, - GRBranchNodeBuilderImpl& BuilderImpl); + GRBranchNodeBuilder& Builder); - void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& BuilderImpl); + void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder); - void ProcessSwitch(GRSwitchNodeBuilderImpl& BuilderImpl); + void ProcessSwitch(GRSwitchNodeBuilder& Builder); private: GRCoreEngine(const GRCoreEngine&); // Do not implement. @@ -122,7 +109,7 @@ public: /// Construct a GRCoreEngine object to analyze the provided CFG using /// a DFS exploration of the exploded graph. GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRSubEngine& subengine) - : SubEngine(subengine), G(new GraphTy(cfg, cd, ctx)), + : SubEngine(subengine), G(new ExplodedGraph(cfg, cd, ctx)), WList(GRWorkList::MakeBFS()), BCounterFactory(G->getAllocator()) {} @@ -131,7 +118,7 @@ public: /// The GRCoreEngine object assumes ownership of 'wlist'. GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRWorkList* wlist, GRSubEngine& subengine) - : SubEngine(subengine), G(new GraphTy(cfg, cd, ctx)), WList(wlist), + : SubEngine(subengine), G(new ExplodedGraph(cfg, cd, ctx)), WList(wlist), BCounterFactory(G->getAllocator()) {} ~GRCoreEngine() { @@ -139,11 +126,11 @@ public: } /// getGraph - Returns the exploded graph. - GraphTy& getGraph() { return *G.get(); } + ExplodedGraph& getGraph() { return *G.get(); } /// takeGraph - Returns the exploded graph. Ownership of the graph is /// transfered to the caller. - GraphTy* takeGraph() { return G.take(); } + ExplodedGraph* takeGraph() { return G.take(); } /// ExecuteWorkList - Run the worklist algorithm for a maximum number of /// steps. Returns true if there is still simulation state on the worklist. @@ -152,59 +139,105 @@ public: CFG& getCFG() { return G->getCFG(); } }; -class GRStmtNodeBuilderImpl { +class GRStmtNodeBuilder { GRCoreEngine& Eng; CFGBlock& B; const unsigned Idx; ExplodedNode* Pred; ExplodedNode* LastNode; + GRStateManager& Mgr; + GRAuditor* Auditor; + +public: + bool PurgingDeadSymbols; + bool BuildSinks; + bool HasGeneratedNode; + ProgramPoint::Kind PointKind; + const void *Tag; + + const GRState* CleanedState; + typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy; DeferredTy Deferred; void GenerateAutoTransition(ExplodedNode* N); public: - GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx, - ExplodedNode* N, GRCoreEngine* e); + GRStmtNodeBuilder(CFGBlock* b, unsigned idx, ExplodedNode* N, + GRCoreEngine* e, GRStateManager &mgr); - ~GRStmtNodeBuilderImpl(); + ~GRStmtNodeBuilder(); ExplodedNode* getBasePredecessor() const { return Pred; } ExplodedNode* getLastNode() const { return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL; } - + + void SetCleanedState(const GRState* St) { + CleanedState = St; + } + GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} unsigned getCurrentBlockCount() const { return getBlockCounter().getNumVisited(B.getBlockID()); } - + + ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) { + HasGeneratedNode = true; + return generateNodeInternal(PP, St, Pred); + } + + ExplodedNode* generateNode(const Stmt* S, const GRState* St, ExplodedNode* Pred, + ProgramPoint::Kind K) { + HasGeneratedNode = true; + + if (PurgingDeadSymbols) + K = ProgramPoint::PostPurgeDeadSymbolsKind; + + return generateNodeInternal(S, St, Pred, K, Tag); + } + + ExplodedNode* generateNode(const Stmt* S, const GRState* St, ExplodedNode* Pred) { + return generateNode(S, St, Pred, PointKind); + } + + ExplodedNode* generateNode(const Stmt* S, const GRState* St, ProgramPoint::Kind K) { + HasGeneratedNode = true; + if (PurgingDeadSymbols) + K = ProgramPoint::PostPurgeDeadSymbolsKind; + return generateNodeInternal(S, St, K, Tag); + } + + ExplodedNode* generateNode(const Stmt* S, const GRState* St) { + return generateNode(S, St, PointKind); + } + ExplodedNode* - generateNodeImpl(const ProgramPoint &PP, const GRState* State, - ExplodedNode* Pred); + generateNodeInternal(const ProgramPoint &PP, const GRState* State, + ExplodedNode* Pred); ExplodedNode* - generateNodeImpl(const Stmt* S, const GRState* State, ExplodedNode* Pred, + generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, const void *tag = 0); ExplodedNode* - generateNodeImpl(const Stmt* S, const GRState* State, + generateNodeInternal(const Stmt* S, const GRState* State, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, const void *tag = 0) { ExplodedNode* N = getLastNode(); assert (N && "Predecessor of new node is infeasible."); - return generateNodeImpl(S, State, N, K, tag); + return generateNodeInternal(S, State, N, K, tag); } ExplodedNode* - generateNodeImpl(const Stmt* S, const GRState* State, const void *tag = 0) { + generateNodeInternal(const Stmt* S,const GRState* State,const void *tag = 0) { ExplodedNode* N = getLastNode(); assert (N && "Predecessor of new node is infeasible."); - return generateNodeImpl(S, State, N, ProgramPoint::PostStmtKind, tag); + return generateNodeInternal(S, State, N, ProgramPoint::PostStmtKind, tag); } /// getStmt - Return the current block-level expression associated with @@ -214,94 +247,25 @@ public: /// getBlock - Return the CFGBlock associated with the block-level expression /// of this builder. CFGBlock* getBlock() const { return &B; } -}; - - -template<typename STATE> -class GRStmtNodeBuilder { -public: - typedef STATE StateTy; - typedef typename StateTy::ManagerTy StateManagerTy; - typedef ExplodedNode NodeTy; - -private: - GRStmtNodeBuilderImpl& NB; - StateManagerTy& Mgr; - const StateTy* CleanedState; - GRAuditor<StateTy>* Auditor; - -public: - GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb, StateManagerTy& mgr) : - NB(nb), Mgr(mgr), Auditor(0), PurgingDeadSymbols(false), - BuildSinks(false), HasGeneratedNode(false), - PointKind(ProgramPoint::PostStmtKind), Tag(0) { - - CleanedState = getLastNode()->getState(); - } - void setAuditor(GRAuditor<StateTy>* A) { - Auditor = A; - } - - NodeTy* getLastNode() const { - return static_cast<NodeTy*>(NB.getLastNode()); - } - - NodeTy* generateNode(PostStmt PP, const StateTy* St, NodeTy* Pred) { - HasGeneratedNode = true; - return static_cast<NodeTy*>(NB.generateNodeImpl(PP, St, Pred)); - } - - NodeTy* generateNode(const Stmt* S, const StateTy* St, NodeTy* Pred, - ProgramPoint::Kind K) { - HasGeneratedNode = true; - if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind; - return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred, K, Tag)); - } - - NodeTy* generateNode(const Stmt* S, const StateTy* St, NodeTy* Pred) { - return generateNode(S, St, Pred, PointKind); - } - - NodeTy* generateNode(const Stmt* S, const StateTy* St, ProgramPoint::Kind K) { - HasGeneratedNode = true; - if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind; - return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, K, Tag)); - } - - NodeTy* generateNode(const Stmt* S, const StateTy* St) { - return generateNode(S, St, PointKind); - } + void setAuditor(GRAuditor* A) { Auditor = A; } - - GRBlockCounter getBlockCounter() const { - return NB.getBlockCounter(); - } - - unsigned getCurrentBlockCount() const { - return NB.getCurrentBlockCount(); - } - - const StateTy* GetState(NodeTy* Pred) const { - if ((ExplodedNode*) Pred == NB.getBasePredecessor()) + const GRState* GetState(ExplodedNode* Pred) const { + if ((ExplodedNode*) Pred == getBasePredecessor()) return CleanedState; else return Pred->getState(); } - - void SetCleanedState(const StateTy* St) { - CleanedState = St; - } - - NodeTy* MakeNode(ExplodedNodeSet& Dst, Stmt* S, - NodeTy* Pred, const StateTy* St) { + + ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred, + const GRState* St) { return MakeNode(Dst, S, Pred, St, PointKind); } - NodeTy* MakeNode(ExplodedNodeSet& Dst, Stmt* S, - NodeTy* Pred, const StateTy* St, ProgramPoint::Kind K) { + ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, + ExplodedNode* Pred, const GRState* St, ProgramPoint::Kind K) { - const StateTy* PredState = GetState(Pred); + const GRState* PredState = GetState(Pred); // If the state hasn't changed, don't generate a new node. if (!BuildSinks && St == PredState && Auditor == 0) { @@ -309,7 +273,7 @@ public: return NULL; } - NodeTy* N = generateNode(S, St, Pred, K); + ExplodedNode* N = generateNode(S, St, Pred, K); if (N) { if (BuildSinks) @@ -325,23 +289,18 @@ public: return N; } - NodeTy* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S, - NodeTy* Pred, const StateTy* St) { + ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S, + ExplodedNode* Pred, const GRState* St) { bool Tmp = BuildSinks; BuildSinks = true; - NodeTy* N = MakeNode(Dst, S, Pred, St); + ExplodedNode* N = MakeNode(Dst, S, Pred, St); BuildSinks = Tmp; return N; } - - bool PurgingDeadSymbols; - bool BuildSinks; - bool HasGeneratedNode; - ProgramPoint::Kind PointKind; - const void *Tag; + }; -class GRBranchNodeBuilderImpl { +class GRBranchNodeBuilder { GRCoreEngine& Eng; CFGBlock* Src; CFGBlock* DstT; @@ -357,19 +316,21 @@ class GRBranchNodeBuilderImpl { bool InFeasibleFalse; public: - GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF, + GRBranchNodeBuilder(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF, ExplodedNode* pred, GRCoreEngine* e) : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred), GeneratedTrue(false), GeneratedFalse(false), InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} - ~GRBranchNodeBuilderImpl(); + ~GRBranchNodeBuilder(); ExplodedNode* getPredecessor() const { return Pred; } + const ExplodedGraph& getGraph() const { return *Eng.G; } + GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} - ExplodedNode* generateNodeImpl(const GRState* State, bool branch); + ExplodedNode* generateNode(const GRState* State, bool branch); CFGBlock* getTargetBlock(bool branch) const { return branch ? DstT : DstF; @@ -385,74 +346,33 @@ public: bool isFeasible(bool branch) { return branch ? !InFeasibleTrue : !InFeasibleFalse; } -}; - -template<typename STATE> -class GRBranchNodeBuilder { - typedef STATE StateTy; - typedef ExplodedGraph GraphTy; - typedef typename GraphTy::NodeTy NodeTy; - GRBranchNodeBuilderImpl& NB; - -public: - GRBranchNodeBuilder(GRBranchNodeBuilderImpl& nb) : NB(nb) {} - - const GraphTy& getGraph() const { - return static_cast<const GraphTy&>(NB.getGraph()); - } - - NodeTy* getPredecessor() const { - return static_cast<NodeTy*>(NB.getPredecessor()); - } - - const StateTy* getState() const { + const GRState* getState() const { return getPredecessor()->getState(); } - - NodeTy* generateNode(const StateTy* St, bool branch) { - return static_cast<NodeTy*>(NB.generateNodeImpl(St, branch)); - } - - GRBlockCounter getBlockCounter() const { - return NB.getBlockCounter(); - } - - CFGBlock* getTargetBlock(bool branch) const { - return NB.getTargetBlock(branch); - } - - void markInfeasible(bool branch) { - NB.markInfeasible(branch); - } - - bool isFeasible(bool branch) { - return NB.isFeasible(branch); - } }; - -class GRIndirectGotoNodeBuilderImpl { + +class GRIndirectGotoNodeBuilder { GRCoreEngine& Eng; CFGBlock* Src; CFGBlock& DispatchBlock; Expr* E; ExplodedNode* Pred; + public: - GRIndirectGotoNodeBuilderImpl(ExplodedNode* pred, CFGBlock* src, - Expr* e, CFGBlock* dispatch, - GRCoreEngine* eng) + GRIndirectGotoNodeBuilder(ExplodedNode* pred, CFGBlock* src, Expr* e, + CFGBlock* dispatch, GRCoreEngine* eng) : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} - - class Iterator { + class iterator { CFGBlock::succ_iterator I; - friend class GRIndirectGotoNodeBuilderImpl; - Iterator(CFGBlock::succ_iterator i) : I(i) {} + friend class GRIndirectGotoNodeBuilder; + iterator(CFGBlock::succ_iterator i) : I(i) {} public: - Iterator& operator++() { ++I; return *this; } - bool operator!=(const Iterator& X) const { return I != X.I; } + iterator& operator++() { ++I; return *this; } + bool operator!=(const iterator& X) const { return I != X.I; } LabelStmt* getLabel() const { return llvm::cast<LabelStmt>((*I)->getLabel()); @@ -463,62 +383,37 @@ public: } }; - Iterator begin() { return Iterator(DispatchBlock.succ_begin()); } - Iterator end() { return Iterator(DispatchBlock.succ_end()); } + iterator begin() { return iterator(DispatchBlock.succ_begin()); } + iterator end() { return iterator(DispatchBlock.succ_end()); } - ExplodedNode* generateNodeImpl(const Iterator& I, const GRState* State, - bool isSink); + ExplodedNode* generateNode(const iterator& I, const GRState* State, + bool isSink = false); Expr* getTarget() const { return E; } - const void* getState() const { return Pred->State; } -}; - -template<typename STATE> -class GRIndirectGotoNodeBuilder { - typedef STATE StateTy; - typedef ExplodedGraph GraphTy; - typedef typename GraphTy::NodeTy NodeTy; - GRIndirectGotoNodeBuilderImpl& NB; - -public: - GRIndirectGotoNodeBuilder(GRIndirectGotoNodeBuilderImpl& nb) : NB(nb) {} - - typedef GRIndirectGotoNodeBuilderImpl::Iterator iterator; - - iterator begin() { return NB.begin(); } - iterator end() { return NB.end(); } - - Expr* getTarget() const { return NB.getTarget(); } - - NodeTy* generateNode(const iterator& I, const StateTy* St, bool isSink=false){ - return static_cast<NodeTy*>(NB.generateNodeImpl(I, St, isSink)); - } - - const StateTy* getState() const { - return static_cast<const StateTy*>(NB.getState()); - } + const GRState* getState() const { return Pred->State; } }; -class GRSwitchNodeBuilderImpl { +class GRSwitchNodeBuilder { GRCoreEngine& Eng; CFGBlock* Src; Expr* Condition; ExplodedNode* Pred; + public: - GRSwitchNodeBuilderImpl(ExplodedNode* pred, CFGBlock* src, - Expr* condition, GRCoreEngine* eng) + GRSwitchNodeBuilder(ExplodedNode* pred, CFGBlock* src, + Expr* condition, GRCoreEngine* eng) : Eng(*eng), Src(src), Condition(condition), Pred(pred) {} - class Iterator { + class iterator { CFGBlock::succ_reverse_iterator I; - friend class GRSwitchNodeBuilderImpl; - Iterator(CFGBlock::succ_reverse_iterator i) : I(i) {} + friend class GRSwitchNodeBuilder; + iterator(CFGBlock::succ_reverse_iterator i) : I(i) {} + public: - - Iterator& operator++() { ++I; return *this; } - bool operator!=(const Iterator& X) const { return I != X.I; } + iterator& operator++() { ++I; return *this; } + bool operator!=(const iterator& X) const { return I != X.I; } CaseStmt* getCase() const { return llvm::cast<CaseStmt>((*I)->getLabel()); @@ -529,113 +424,49 @@ public: } }; - Iterator begin() { return Iterator(Src->succ_rbegin()+1); } - Iterator end() { return Iterator(Src->succ_rend()); } + iterator begin() { return iterator(Src->succ_rbegin()+1); } + iterator end() { return iterator(Src->succ_rend()); } - ExplodedNode* generateCaseStmtNodeImpl(const Iterator& I, - const GRState* State); + ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State); - ExplodedNode* generateDefaultCaseNodeImpl(const GRState* State, - bool isSink); + ExplodedNode* generateDefaultCaseNode(const GRState* State, + bool isSink = false); Expr* getCondition() const { return Condition; } - const void* getState() const { return Pred->State; } -}; -template<typename STATE> -class GRSwitchNodeBuilder { - typedef STATE StateTy; - typedef ExplodedGraph GraphTy; - typedef typename GraphTy::NodeTy NodeTy; - - GRSwitchNodeBuilderImpl& NB; - -public: - GRSwitchNodeBuilder(GRSwitchNodeBuilderImpl& nb) : NB(nb) {} - - typedef GRSwitchNodeBuilderImpl::Iterator iterator; - - iterator begin() { return NB.begin(); } - iterator end() { return NB.end(); } - - Expr* getCondition() const { return NB.getCondition(); } - - NodeTy* generateCaseStmtNode(const iterator& I, const StateTy* St) { - return static_cast<NodeTy*>(NB.generateCaseStmtNodeImpl(I, St)); - } - - NodeTy* generateDefaultCaseNode(const StateTy* St, bool isSink = false) { - return static_cast<NodeTy*>(NB.generateDefaultCaseNodeImpl(St, isSink)); - } - - const StateTy* getState() const { - return static_cast<const StateTy*>(NB.getState()); - } + const GRState* getState() const { return Pred->State; } }; - -class GREndPathNodeBuilderImpl { +class GREndPathNodeBuilder { GRCoreEngine& Eng; CFGBlock& B; ExplodedNode* Pred; bool HasGeneratedNode; public: - GREndPathNodeBuilderImpl(CFGBlock* b, ExplodedNode* N, - GRCoreEngine* e) + GREndPathNodeBuilder(CFGBlock* b, ExplodedNode* N, GRCoreEngine* e) : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {} - ~GREndPathNodeBuilderImpl(); + ~GREndPathNodeBuilder(); ExplodedNode* getPredecessor() const { return Pred; } - GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} + GRBlockCounter getBlockCounter() const { + return Eng.WList->getBlockCounter(); + } unsigned getCurrentBlockCount() const { return getBlockCounter().getNumVisited(B.getBlockID()); } - ExplodedNode* generateNodeImpl(const GRState* State, - const void *tag = 0, - ExplodedNode *P = 0); + ExplodedNode* generateNode(const GRState* State, const void *tag = 0, + ExplodedNode *P = 0); CFGBlock* getBlock() const { return &B; } -}; - -template<typename STATE> -class GREndPathNodeBuilder { - typedef STATE StateTy; - typedef ExplodedNode NodeTy; - - GREndPathNodeBuilderImpl& NB; - -public: - GREndPathNodeBuilder(GREndPathNodeBuilderImpl& nb) : NB(nb) {} - - NodeTy* getPredecessor() const { - return static_cast<NodeTy*>(NB.getPredecessor()); - } - - GRBlockCounter getBlockCounter() const { - return NB.getBlockCounter(); - } - - unsigned getCurrentBlockCount() const { - return NB.getCurrentBlockCount(); - } - - const StateTy* getState() const { + const GRState* getState() const { return getPredecessor()->getState(); } - - NodeTy* MakeNode(const StateTy* St, const void *tag = 0) { - return static_cast<NodeTy*>(NB.generateNodeImpl(St, tag)); - } - - NodeTy *generateNode(const StateTy *St, NodeTy *Pred, const void *tag = 0) { - return static_cast<NodeTy*>(NB.generateNodeImpl(St, tag, Pred)); - } }; } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 12c63525f3..7b29039714 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -33,24 +33,11 @@ namespace clang { class Checker; class GRExprEngine : public GRSubEngine { -public: - typedef GRState StateTy; - typedef ExplodedGraph GraphTy; - typedef GraphTy::NodeTy NodeTy; - - // Builders. - typedef GRStmtNodeBuilder<StateTy> StmtNodeBuilder; - typedef GRBranchNodeBuilder<StateTy> BranchNodeBuilder; - typedef GRIndirectGotoNodeBuilder<StateTy> IndirectGotoNodeBuilder; - typedef GRSwitchNodeBuilder<StateTy> SwitchNodeBuilder; - typedef GREndPathNodeBuilder<StateTy> EndPathNodeBuilder; - typedef ExplodedNodeSet NodeSet; - protected: GRCoreEngine CoreEngine; /// G - the simulation graph. - GraphTy& G; + ExplodedGraph& G; /// Liveness - live-variables information the ValueDecl* and block-level /// Expr* in the CFG. Used to prune out dead state. @@ -58,7 +45,7 @@ protected: /// Builder - The current GRStmtNodeBuilder which is used when building the /// nodes for a given statement. - StmtNodeBuilder* Builder; + GRStmtNodeBuilder* Builder; /// StateMgr - Object that manages the data for all created states. GRStateManager StateMgr; @@ -73,7 +60,7 @@ protected: SValuator &SVator; /// EntryNode - The immediate predecessor node. - NodeTy* EntryNode; + ExplodedNode* EntryNode; /// CleanedState - The state for EntryNode "cleaned" of all dead /// variables and symbols (as determined by a liveness analysis). @@ -110,8 +97,8 @@ protected: const bool EagerlyAssume; public: - typedef llvm::SmallPtrSet<NodeTy*,2> ErrorNodes; - typedef llvm::DenseMap<NodeTy*, Expr*> UndefArgsTy; + typedef llvm::SmallPtrSet<ExplodedNode*,2> ErrorNodes; + typedef llvm::DenseMap<ExplodedNode*, Expr*> UndefArgsTy; /// NilReceiverStructRetExplicit - Nodes in the ExplodedGraph that resulted /// from [x ...] with 'x' definitely being nil and the result was a 'struct' @@ -248,7 +235,7 @@ public: /// simulation. void ViewGraph(bool trim = false); - void ViewGraph(NodeTy** Beg, NodeTy** End); + void ViewGraph(ExplodedNode** Beg, ExplodedNode** End); /// getLiveness - Returned computed live-variables information for the /// analyzed function. @@ -259,8 +246,8 @@ public: /// in the ExplodedGraph. const GRState* getInitialState(); - GraphTy& getGraph() { return G; } - const GraphTy& getGraph() const { return G; } + ExplodedGraph& getGraph() { return G; } + const ExplodedGraph& getGraph() const { return G; } void RegisterInternalChecks(); @@ -268,58 +255,58 @@ public: Checkers.push_back(check); } - bool isRetStackAddr(const NodeTy* N) const { - return N->isSink() && RetsStackAddr.count(const_cast<NodeTy*>(N)) != 0; + bool isRetStackAddr(const ExplodedNode* N) const { + return N->isSink() && RetsStackAddr.count(const_cast<ExplodedNode*>(N)) != 0; } - bool isUndefControlFlow(const NodeTy* N) const { - return N->isSink() && UndefBranches.count(const_cast<NodeTy*>(N)) != 0; + bool isUndefControlFlow(const ExplodedNode* N) const { + return N->isSink() && UndefBranches.count(const_cast<ExplodedNode*>(N)) != 0; } - bool isUndefStore(const NodeTy* N) const { - return N->isSink() && UndefStores.count(const_cast<NodeTy*>(N)) != 0; + bool isUndefStore(const ExplodedNode* N) const { + return N->isSink() && UndefStores.count(const_cast<ExplodedNode*>(N)) != 0; } - bool isImplicitNullDeref(const NodeTy* N) const { - return N->isSink() && ImplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0; + bool isImplicitNullDeref(const ExplodedNode* N) const { + return N->isSink() && ImplicitNullDeref.count(const_cast<ExplodedNode*>(N)) != 0; } - bool isExplicitNullDeref(const NodeTy* N) const { - return N->isSink() && ExplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0; + bool isExplicitNullDeref(const ExplodedNode* N) const { + return N->isSink() && ExplicitNullDeref.count(const_cast<ExplodedNode*>(N)) != 0; } - bool isUndefDeref(const NodeTy* N) const { - return N->isSink() && UndefDeref.count(const_cast<NodeTy*>(N)) != 0; + bool isUndefDeref(const ExplodedNode* N) const { |