diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/Checker.h | 102 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/CheckerVisitor.def | 17 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/CheckerVisitor.h | 54 |
3 files changed, 173 insertions, 0 deletions
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h new file mode 100644 index 0000000000..9c32d16458 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/Checker.h @@ -0,0 +1,102 @@ +//== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines Checker and CheckerVisitor, classes used for creating +// domain-specific checks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_CHECKER +#define LLVM_CLANG_ANALYSIS_CHECKER +#include "clang/Analysis/Support/SaveAndRestore.h" +#include "clang/Analysis/PathSensitive/GRCoreEngine.h" +#include "clang/Analysis/PathSensitive/GRState.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" +#include "clang/AST/StmtCXX.h" +#include "clang/AST/StmtObjC.h" + +//===----------------------------------------------------------------------===// +// Checker interface. +//===----------------------------------------------------------------------===// + +namespace clang { + class GRExprEngine; + +class CheckerContext { + ExplodedNodeSet<GRState> &Dst; + GRStmtNodeBuilder<GRState> &B; + GRExprEngine &Eng; + ExplodedNode<GRState> *Pred; + SaveAndRestore<bool> OldSink; + SaveAndRestore<const void*> OldTag; + SaveAndRestore<ProgramPoint::Kind> OldPointKind; + SaveOr OldHasGen; + +public: + CheckerContext(ExplodedNodeSet<GRState> &dst, + GRStmtNodeBuilder<GRState> &builder, + GRExprEngine &eng, + ExplodedNode<GRState> *pred, + const void *tag, bool preVisit) + : Dst(dst), B(builder), Eng(eng), Pred(pred), + OldSink(B.BuildSinks), OldTag(B.Tag), + OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) { + assert(Dst.empty()); + B.Tag = tag; + if (preVisit) + B.PointKind = ProgramPoint::PreStmtKind; + } + + ~CheckerContext() { + if (!B.BuildSinks && Dst.empty() && !B.HasGeneratedNode) + Dst.Add(Pred); + } + + ConstraintManager &getConstraintManager() { + return Eng.getConstraintManager(); + } + ExplodedNodeSet<GRState> &getNodeSet() { return Dst; } + GRStmtNodeBuilder<GRState> &getNodeBuilder() { return B; } + ExplodedNode<GRState> *&getPredecessor() { return Pred; } + const GRState *getState() { return B.GetState(Pred); } + + ExplodedNode<GRState> *generateNode(const Stmt* S, + const GRState *state) { + return B.generateNode(S, state, Pred); + } + + void EmitReport(BugReport *R) { + Eng.getBugReporter().EmitReport(R); + } +}; + +class Checker { +private: + friend class GRExprEngine; + + void GR_Visit(ExplodedNodeSet<GRState> &Dst, + GRStmtNodeBuilder<GRState> &Builder, + GRExprEngine &Eng, + const Stmt *stmt, + ExplodedNode<GRState> *Pred, bool isPrevisit) { + CheckerContext C(Dst, Builder, Eng, Pred, getTag(), isPrevisit); + assert(isPrevisit && "Only previsit supported for now."); + _PreVisit(C, stmt); + } + +public: + virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) = 0; + virtual const void *getTag() = 0; +}; + +} // end clang namespace + +#endif +
\ No newline at end of file diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Analysis/PathSensitive/CheckerVisitor.def new file mode 100644 index 0000000000..b3d09d0f91 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.def @@ -0,0 +1,17 @@ +//===-- CheckerVisitor.def - Metadata for CheckerVisitor ----------------*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the AST nodes accepted by the CheckerVisitor class. +// +//===---------------------------------------------------------------------===// + +PREVISIT(CallExpr) +PREVISIT(ObjCMessageExpr) + +#undef PREVISIT diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Analysis/PathSensitive/CheckerVisitor.h new file mode 100644 index 0000000000..91db783a53 --- /dev/null +++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.h @@ -0,0 +1,54 @@ +//== CheckerVisitor.h - Abstract visitor for checkers ------------*- C++ -*--=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines CheckerVisitor. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_CHECKERVISITOR +#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR +#include "clang/Analysis/PathSensitive/Checker.h" + +namespace clang { + +//===----------------------------------------------------------------------===// +// Checker visitor interface. Used by subclasses of Checker to specify their +// own checker visitor logic. +//===----------------------------------------------------------------------===// + +/// CheckerVisitor - This class implements a simple visitor for Stmt subclasses. +/// Since Expr derives from Stmt, this also includes support for visiting Exprs. +template<typename ImplClass> +class CheckerVisitor : public Checker { +public: + virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) { + PreVisit(C, stmt); + } + + void PreVisit(CheckerContext &C, const Stmt *S) { + switch (S->getStmtClass()) { + default: + assert(false && "Unsupport statement."); + return; +#define PREVISIT(NAME) \ +case Stmt::NAME ## Class:\ +static_cast<ImplClass*>(this)->PreVisit ## NAME(C, static_cast<const NAME*>(S)); +#include "clang/Analysis/PathSensitive/CheckerVisitor.def" + } + } + +#define PREVISIT(NAME) \ +void PreVisit ## NAME(CheckerContext &C, const NAME* S) {} +#include "clang/Analysis/PathSensitive/CheckerVisitor.def" +}; + +} // end clang namespace + +#endif +
\ No newline at end of file |