aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-11-11 03:26:34 +0000
committerTed Kremenek <kremenek@apple.com>2009-11-11 03:26:34 +0000
commitb4b817d704287836b52b34369009e682f208aa2b (patch)
tree2b7898371d40dd14735954712fd2344baa2a7b63 /include/clang/Analysis
parent09b6d0e7931bf72674e4d752bd66b566cc01fe05 (diff)
Refactor DereferenceChecker to use only the new Checker API instead of
the old builder API. This percolated a bunch of changes up to the Checker class (where CheckLocation has been renamed VisitLocation) and GRExprEngine. ProgramPoint now has the notion of a "LocationCheck" point (with PreLoad and PreStore respectively), and a bunch of the old ProgramPoints that are no longer used have been removed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86798 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis')
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h68
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h32
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h13
-rw-r--r--include/clang/Analysis/ProgramPoint.h64
4 files changed, 77 insertions, 100 deletions
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 5e87e37993..5503a9099b 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -39,22 +39,19 @@ class CheckerContext {
SaveAndRestore<const void*> OldTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
+ const GRState *state;
public:
- CheckerContext(ExplodedNodeSet &dst,
- GRStmtNodeBuilder &builder,
- GRExprEngine &eng,
- ExplodedNode *pred,
- const void *tag, bool preVisit)
+ CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
+ GRExprEngine &eng, ExplodedNode *pred,
+ const void *tag, ProgramPoint::Kind K,
+ const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
- OldSink(B.BuildSinks), OldTag(B.Tag),
- OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) {
- //assert(Dst.empty()); // This is a fake assertion.
- // See GRExprEngine::CheckerVisit(), CurrSet is repeatedly used.
- B.Tag = tag;
- if (preVisit)
- B.PointKind = ProgramPoint::PreStmtKind;
- }
+ OldSink(B.BuildSinks),
+ OldTag(B.Tag, tag),
+ OldPointKind(B.PointKind, K),
+ OldHasGen(B.HasGeneratedNode),
+ state(st) {}
~CheckerContext() {
if (!B.BuildSinks && !B.HasGeneratedNode)
@@ -72,7 +69,7 @@ public:
ExplodedNodeSet &getNodeSet() { return Dst; }
GRStmtNodeBuilder &getNodeBuilder() { return B; }
ExplodedNode *&getPredecessor() { return Pred; }
- const GRState *getState() { return B.GetState(Pred); }
+ const GRState *getState() { return state ? state : B.GetState(Pred); }
ASTContext &getASTContext() {
return Eng.getContext();
@@ -113,43 +110,54 @@ class Checker {
private:
friend class GRExprEngine;
+ // FIXME: Remove the 'tag' option.
void GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
- const Stmt *stmt,
+ const Stmt *S,
ExplodedNode *Pred, void *tag, bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
assert(isPrevisit && "Only previsit supported for now.");
- _PreVisit(C, stmt);
+ _PreVisit(C, S);
}
+ // FIXME: Remove the 'tag' option.
void GR_VisitBind(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
const Stmt *AssignE,
const Stmt *StoreE, ExplodedNode *Pred, void *tag,
SVal location, SVal val,
bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
assert(isPrevisit && "Only previsit supported for now.");
PreVisitBind(C, AssignE, StoreE, location, val);
}
+
+ // FIXME: Remove the 'tag' option.
+ void GR_VisitLocation(ExplodedNodeSet &Dst,
+ GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ const Stmt *S,
+ ExplodedNode *Pred, const GRState *state,
+ SVal location,
+ void *tag, bool isLoad) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isLoad ? ProgramPoint::PreLoadKind :
+ ProgramPoint::PreStoreKind, state);
+ VisitLocation(C, S, location);
+ }
public:
virtual ~Checker() {}
virtual void _PreVisit(CheckerContext &C, const Stmt *ST) {}
-
- // This is a previsit which takes a node returns a node.
- virtual ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V,
- GRExprEngine &Eng) {
- return Pred;
- }
-
- virtual void PreVisitBind(CheckerContext &C,
- const Stmt *AssignE, const Stmt *StoreE,
- SVal location, SVal val) {}
+ virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
+ virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+ const Stmt *StoreE, SVal location, SVal val) {}
};
-
} // end clang namespace
#endif
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
index 688cf64149..a84183e7f2 100644
--- a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
+++ b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
@@ -16,38 +16,16 @@
#ifndef LLVM_CLANG_DEREFCHECKER
#define LLVM_CLANG_DEREFCHECKER
-#include "clang/Analysis/PathSensitive/Checker.h"
-#include "clang/Analysis/PathSensitive/BugType.h"
+#include <utility>
namespace clang {
+class GRExprEngine;
class ExplodedNode;
-class NullDerefChecker : public Checker {
- BuiltinBug *BT;
- llvm::SmallVector<ExplodedNode*, 2> ImplicitNullDerefNodes;
-
-public:
- NullDerefChecker() : BT(0) {}
- ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V,GRExprEngine &Eng);
-
- static void *getTag();
- typedef llvm::SmallVectorImpl<ExplodedNode*>::iterator iterator;
- iterator implicit_nodes_begin() { return ImplicitNullDerefNodes.begin(); }
- iterator implicit_nodes_end() { return ImplicitNullDerefNodes.end(); }
-};
-
-class UndefDerefChecker : public Checker {
- BuiltinBug *BT;
-public:
- UndefDerefChecker() : BT(0) {}
-
- ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V, GRExprEngine &Eng);
-
- static void *getTag();
-};
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+GetImplicitNullDereferences(GRExprEngine &Eng);
} // end clang namespace
+
#endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index db8720987c..0445896311 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -556,16 +556,21 @@ protected:
bool atDeclInit = false);
public:
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
const GRState* St, SVal location, const void *tag = 0);
- ExplodedNode* EvalLocation(Stmt* Ex, ExplodedNode* Pred,
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
const GRState* St, SVal location,
- const void *tag = 0);
+ const void *tag, bool isLoad);
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
- ExplodedNode* Pred,
- const GRState* St, SVal TargetLV, SVal Val,
+ ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
const void *tag = 0);
};
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 7aaae9c866..75ae83f0a6 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -33,13 +33,10 @@ public:
BlockEntranceKind,
BlockExitKind,
PreStmtKind,
- // Keep the following together and in this order.
PostStmtKind,
- PostLocationChecksSucceedKind,
- PostOutOfBoundsCheckFailedKind,
- PostNullCheckFailedKind,
- PostUndefLocationCheckFailedKind,
+ PreLoadKind,
PostLoadKind,
+ PreStoreKind,
PostStoreKind,
PostPurgeDeadSymbolsKind,
PostStmtCustomKind,
@@ -194,17 +191,6 @@ public:
}
};
-class PostLocationChecksSucceed : public PostStmt {
-public:
- PostLocationChecksSucceed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostLocationChecksSucceedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLocationChecksSucceedKind;
- }
-};
-
class PostStmtCustom : public PostStmt {
public:
PostStmtCustom(const Stmt* S,
@@ -226,36 +212,36 @@ public:
}
};
-class PostOutOfBoundsCheckFailed : public PostStmt {
-public:
- PostOutOfBoundsCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostOutOfBoundsCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostOutOfBoundsCheckFailedKind;
+
+class LocationCheck : public StmtPoint {
+protected:
+ LocationCheck(const Stmt *S, const LocationContext *L,
+ ProgramPoint::Kind K, const void *tag)
+ : StmtPoint(S, NULL, K, L, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ unsigned k = location->getKind();
+ return k == PreLoadKind || PreStoreKind;
}
};
-
-class PostUndefLocationCheckFailed : public PostStmt {
+
+class PreLoad : public LocationCheck {
public:
- PostUndefLocationCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostUndefLocationCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostUndefLocationCheckFailedKind;
+ PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreLoadKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreLoadKind;
}
};
-class PostNullCheckFailed : public PostStmt {
+class PreStore : public LocationCheck {
public:
- PostNullCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostNullCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostNullCheckFailedKind;
+ PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreStoreKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreStoreKind;
}
};