aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-06-18 05:34:07 +0000
committerTed Kremenek <kremenek@apple.com>2008-06-18 05:34:07 +0000
commit331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434f (patch)
treeffb6b8127a7735a6996f4777740a1c8a135530a8 /include/clang/Analysis
parent60c5e4263b5146aa6c82ef1b6c1dbd391a285c95 (diff)
Added a new ProgramPoint: PostPurgeDeadSymbols. This new program point distinguishes between the cases when we just evaluated the transfer function of a Stmt* (PostStmt) or performed a load (PostLoad). This solves a caching bug observed in a recent bug report.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52443 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis')
-rw-r--r--include/clang/Analysis/PathSensitive/GRCoreEngine.h71
-rw-r--r--include/clang/Analysis/ProgramPoint.h18
2 files changed, 57 insertions, 32 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
index aa8ca231b0..5cb4fd7d52 100644
--- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
@@ -149,20 +149,25 @@ public:
unsigned getCurrentBlockCount() const {
return getBlockCounter().getNumVisited(B.getBlockID());
}
-
- ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State,
- ExplodedNodeImpl* Pred,
- bool isLoad = false);
+
+ ExplodedNodeImpl*
+ generateNodeImpl(Stmt* S, void* State, ExplodedNodeImpl* Pred,
+ ProgramPoint::Kind K = ProgramPoint::PostStmtKind);
- inline ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State,
- bool isLoad = false) {
+ ExplodedNodeImpl*
+ generateNodeImpl(Stmt* S, void* State,
+ ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
ExplodedNodeImpl* N = getLastNode();
assert (N && "Predecessor of new node is infeasible.");
- return generateNodeImpl(S, State, N, isLoad);
+ return generateNodeImpl(S, State, N, K);
}
+ /// getStmt - Return the current block-level expression associated with
+ /// this builder.
Stmt* getStmt() const { return B[Idx]; }
+ /// getBlock - Return the CFGBlock associated with the block-level expression
+ /// of this builder.
CFGBlock* getBlock() const { return &B; }
};
@@ -182,6 +187,7 @@ public:
GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb),
CallExprAuditBeg(0), CallExprAuditEnd(0),
ObjCMsgExprAuditBeg(0), ObjCMsgExprAuditEnd(0),
+ PurgingDeadSymbols(false),
BuildSinks(false), HasGeneratedNode(false) {
CleanedState = getLastNode()->getState();
@@ -203,14 +209,22 @@ public:
return static_cast<NodeTy*>(NB.getLastNode());
}
- NodeTy* generateNode(Stmt* S, StateTy* St, NodeTy* Pred, bool isLoad = false){
+ NodeTy*
+ generateNode(Stmt* S, StateTy* St, NodeTy* Pred,
+ ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
+
HasGeneratedNode = true;
- return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred, isLoad));
+ if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind;
+ return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred, K));
}
- NodeTy* generateNode(Stmt* S, StateTy* St, bool isLoad = false) {
+ NodeTy*
+ generateNode(Stmt* S, StateTy* St,
+ ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
+
HasGeneratedNode = true;
- return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, isLoad));
+ if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind;
+ return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, K));
}
GRBlockCounter getBlockCounter() const {
@@ -274,6 +288,7 @@ public:
return N;
}
+ bool PurgingDeadSymbols;
bool BuildSinks;
bool HasGeneratedNode;
};
@@ -338,7 +353,7 @@ public:
return getPredecessor()->getState();
}
- inline NodeTy* generateNode(StateTy* St, bool branch) {
+ NodeTy* generateNode(StateTy* St, bool branch) {
return static_cast<NodeTy*>(NB.generateNodeImpl(St, branch));
}
@@ -350,7 +365,7 @@ public:
return NB.getTargetBlock(branch);
}
- inline void markInfeasible(bool branch) {
+ void markInfeasible(bool branch) {
NB.markInfeasible(branch);
}
};
@@ -393,8 +408,8 @@ public:
ExplodedNodeImpl* generateNodeImpl(const Iterator& I, void* State,
bool isSink);
- inline Expr* getTarget() const { return E; }
- inline void* getState() const { return Pred->State; }
+ Expr* getTarget() const { return E; }
+ void* getState() const { return Pred->State; }
};
template<typename STATE>
@@ -410,16 +425,16 @@ public:
typedef GRIndirectGotoNodeBuilderImpl::Iterator iterator;
- inline iterator begin() { return NB.begin(); }
- inline iterator end() { return NB.end(); }
+ iterator begin() { return NB.begin(); }
+ iterator end() { return NB.end(); }
- inline Expr* getTarget() const { return NB.getTarget(); }
+ Expr* getTarget() const { return NB.getTarget(); }
- inline NodeTy* generateNode(const iterator& I, StateTy* St, bool isSink=false){
+ NodeTy* generateNode(const iterator& I, StateTy* St, bool isSink=false){
return static_cast<NodeTy*>(NB.generateNodeImpl(I, St, isSink));
}
- inline StateTy* getState() const {
+ StateTy* getState() const {
return static_cast<StateTy*>(NB.getState());
}
};
@@ -459,8 +474,8 @@ public:
ExplodedNodeImpl* generateCaseStmtNodeImpl(const Iterator& I, void* State);
ExplodedNodeImpl* generateDefaultCaseNodeImpl(void* State, bool isSink);
- inline Expr* getCondition() const { return Condition; }
- inline void* getState() const { return Pred->State; }
+ Expr* getCondition() const { return Condition; }
+ void* getState() const { return Pred->State; }
};
template<typename STATE>
@@ -476,20 +491,20 @@ public:
typedef GRSwitchNodeBuilderImpl::Iterator iterator;
- inline iterator begin() { return NB.begin(); }
- inline iterator end() { return NB.end(); }
+ iterator begin() { return NB.begin(); }
+ iterator end() { return NB.end(); }
- inline Expr* getCondition() const { return NB.getCondition(); }
+ Expr* getCondition() const { return NB.getCondition(); }
- inline NodeTy* generateCaseStmtNode(const iterator& I, StateTy* St) {
+ NodeTy* generateCaseStmtNode(const iterator& I, StateTy* St) {
return static_cast<NodeTy*>(NB.generateCaseStmtNodeImpl(I, St));
}
- inline NodeTy* generateDefaultCaseNode(StateTy* St, bool isSink = false) {
+ NodeTy* generateDefaultCaseNode(StateTy* St, bool isSink = false) {
return static_cast<NodeTy*>(NB.generateDefaultCaseNodeImpl(St, isSink));
}
- inline StateTy* getState() const {
+ StateTy* getState() const {
return static_cast<StateTy*>(NB.getState());
}
};
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index efd16b416d..ecb4f742c7 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -25,9 +25,10 @@ namespace clang {
class ProgramPoint {
public:
- enum Kind { BlockEntranceKind=0, PostStmtKind=1, PostLoadKind=2,
- BlockExitKind=3, BlockEdgeSrcKind=4, BlockEdgeDstKind=5,
- BlockEdgeAuxKind=6 };
+ enum Kind { BlockEntranceKind=0,
+ PostStmtKind=1, PostLoadKind=2, PostPurgeDeadSymbolsKind=3,
+ BlockExitKind=4, BlockEdgeSrcKind=5, BlockEdgeDstKind=6,
+ BlockEdgeAuxKind=7 };
protected:
uintptr_t Data;
@@ -110,7 +111,7 @@ public:
static bool classof(const ProgramPoint* Location) {
unsigned k = Location->getKind();
- return k == PostStmtKind || k == PostLoadKind;
+ return k >= PostStmtKind && k <= PostPurgeDeadSymbolsKind;
}
};
@@ -123,6 +124,15 @@ public:
}
};
+class PostPurgeDeadSymbols : public PostStmt {
+public:
+ PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {}
+
+ static bool classof(const ProgramPoint* Location) {
+ return Location->getKind() == PostPurgeDeadSymbolsKind;
+ }
+};
+
class BlockEdge : public ProgramPoint {
typedef std::pair<CFGBlock*,CFGBlock*> BPair;
public: