aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-08-06 12:48:26 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-08-06 12:48:26 +0000
commit031ccc0555a82afc2e8afe29e19dd57ff204e2de (patch)
tree089d9ca5c64d376bf5a4880015664039bf35e66f
parent0111f575b968e423dccae439e501225b8314b257 (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.h10
-rw-r--r--include/clang/Analysis/PathSensitive/ExplodedGraph.h10
-rw-r--r--include/clang/Analysis/PathSensitive/GRAuditor.h12
-rw-r--r--include/clang/Analysis/PathSensitive/GRCoreEngine.h449
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h187
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h14
-rw-r--r--include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h2
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h10
-rw-r--r--lib/Analysis/BasicObjCFoundationChecks.cpp14
-rw-r--r--lib/Analysis/CFRefCount.cpp50
-rw-r--r--lib/Analysis/CheckNSError.cpp6
-rw-r--r--lib/Analysis/GRCoreEngine.cpp101
-rw-r--r--lib/Analysis/GRExprEngine.cpp354
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp2
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 {