diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-11-11 03:26:34 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-11-11 03:26:34 +0000 |
commit | b4b817d704287836b52b34369009e682f208aa2b (patch) | |
tree | 2b7898371d40dd14735954712fd2344baa2a7b63 /include/clang/Analysis | |
parent | 09b6d0e7931bf72674e4d752bd66b566cc01fe05 (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.h | 68 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h | 32 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 13 | ||||
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 64 |
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; } }; |