summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/PathSensitive/Checker.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/PathSensitive/Checker.h')
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h74
1 files changed, 54 insertions, 20 deletions
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 91a4b6d..a625a7a 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -39,7 +39,7 @@ class CheckerContext {
SaveAndRestore<const void*> OldTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
- const GRState *state;
+ const GRState *ST;
const Stmt *statement;
const unsigned size;
bool DoneEvaluating; // FIXME: This is not a permanent API change.
@@ -53,22 +53,14 @@ public:
OldTag(B.Tag, tag),
OldPointKind(B.PointKind, K),
OldHasGen(B.HasGeneratedNode),
- state(st), statement(stmt), size(Dst.size()),
- DoneEvaluating(false) {}
+ ST(st), statement(stmt), size(Dst.size()) {}
~CheckerContext();
-
- // FIXME: This were added to support CallAndMessageChecker to indicating
- // to GRExprEngine to "stop evaluating" a message expression under certain
- // cases. This is *not* meant to be a permanent API change, and was added
- // to aid in the transition of removing logic for checks from GRExprEngine.
- void setDoneEvaluating() {
- DoneEvaluating = true;
- }
- bool isDoneEvaluating() const {
- return DoneEvaluating;
+
+ GRExprEngine &getEngine() {
+ return Eng;
}
-
+
ConstraintManager &getConstraintManager() {
return Eng.getConstraintManager();
}
@@ -80,7 +72,7 @@ public:
ExplodedNodeSet &getNodeSet() { return Dst; }
GRStmtNodeBuilder &getNodeBuilder() { return B; }
ExplodedNode *&getPredecessor() { return Pred; }
- const GRState *getState() { return state ? state : B.GetState(Pred); }
+ const GRState *getState() { return ST ? ST : B.GetState(Pred); }
ASTContext &getASTContext() {
return Eng.getContext();
@@ -98,6 +90,10 @@ public:
return Eng.getValueManager();
}
+ SValuator &getSValuator() {
+ return Eng.getSValuator();
+ }
+
ExplodedNode *GenerateNode(bool autoTransition = true) {
assert(statement && "Only transitions with statements currently supported");
ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
@@ -115,6 +111,15 @@ public:
return N;
}
+ ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred,
+ bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
+
ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
assert(statement && "Only transitions with statements currently supported");
ExplodedNode *N = GenerateNodeImpl(statement, state, false);
@@ -138,8 +143,7 @@ public:
void addTransition(const GRState *state) {
assert(state);
- if (state != getState() ||
- (state && state != B.GetState(Pred)))
+ if (state != getState() || (ST && ST != B.GetState(Pred)))
GenerateNode(state, true);
else
Dst.Add(Pred);
@@ -157,7 +161,14 @@ private:
node->markAsSink();
return node;
}
-
+
+ ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+ ExplodedNode *pred, bool markAsSink) {
+ ExplodedNode *node = B.generateNode(stmt, state, pred);
+ if (markAsSink && node)
+ node->markAsSink();
+ return node;
+ }
};
class Checker {
@@ -165,7 +176,7 @@ private:
friend class GRExprEngine;
// FIXME: Remove the 'tag' option.
- bool GR_Visit(ExplodedNodeSet &Dst,
+ void GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
const Stmt *S,
@@ -177,7 +188,22 @@ private:
_PreVisit(C, S);
else
_PostVisit(C, S);
- return C.isDoneEvaluating();
+ }
+
+ bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const ObjCMessageExpr *ME,
+ ExplodedNode *Pred, const GRState *state, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+ ME, state);
+ return EvalNilReceiver(C, ME);
+ }
+
+ bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const CallExpr *CE,
+ ExplodedNode *Pred, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+ CE);
+ return EvalCallExpr(C, CE);
}
// FIXME: Remove the 'tag' option.
@@ -231,6 +257,14 @@ public:
virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
GRExprEngine &Eng,
Stmt *Condition, void *tag) {}
+
+ virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
+ return false;
+ }
+
+ virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+ return false;
+ }
};
} // end clang namespace
OpenPOWER on IntegriCloud