From 01af97d3b23bded2b2b21af19bbc6e4cce49e5b3 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 2 May 2011 19:39:53 +0000 Subject: Vendor import of clang trunk r130700: http://llvm.org/svn/llvm-project/cfe/trunk@130700 --- include/clang/StaticAnalyzer/Core/CheckerManager.h | 206 ++++++++++++++------- 1 file changed, 140 insertions(+), 66 deletions(-) (limited to 'include/clang/StaticAnalyzer/Core/CheckerManager.h') diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 276819549d1a8..92ec0388e500b 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -37,6 +37,7 @@ namespace ento { class ExplodedGraph; class GRState; class EndOfFunctionNodeBuilder; + class BranchNodeBuilder; class MemRegion; class SymbolReaper; @@ -46,47 +47,46 @@ public: virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0; }; -struct VoidCheckerFnParm {}; -template -class CheckerFn { - typedef void (*Func)(void *, P1, P2, P3, P4); +template class CheckerFn; + +template +class CheckerFn { + typedef RET (*Func)(void *, P1, P2, P3); Func Fn; public: void *Checker; CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } - void operator()(P1 p1, P2 p2, P3 p3, P4 p4) { Fn(Checker, p1, p2, p3, p4); } + RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } }; -template -class CheckerFn { - typedef void (*Func)(void *, P1, P2, P3); +template +class CheckerFn { + typedef RET (*Func)(void *, P1, P2); Func Fn; public: void *Checker; CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } - void operator()(P1 p1, P2 p2, P3 p3) { Fn(Checker, p1, p2, p3); } + RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } }; -template -class CheckerFn { - typedef void (*Func)(void *, P1, P2); +template +class CheckerFn { + typedef RET (*Func)(void *, P1); Func Fn; public: void *Checker; CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } - void operator()(P1 p1, P2 p2) { Fn(Checker, p1, p2); } + RET operator()(P1 p1) const { return Fn(Checker, p1); } }; -template <> -class CheckerFn { - typedef void (*Func)(void *); +template +class CheckerFn { + typedef RET (*Func)(void *); Func Fn; public: void *Checker; CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } - void operator()() { Fn(Checker); } + RET operator()() const { return Fn(Checker); } }; class CheckerManager { @@ -96,21 +96,35 @@ public: CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } ~CheckerManager(); + bool hasPathSensitiveCheckers() const; + + void finishedCheckerRegistration(); + const LangOptions &getLangOptions() const { return LangOpts; } typedef void *CheckerRef; - typedef CheckerFn<> CheckerDtor; + typedef void *CheckerTag; + typedef CheckerFn CheckerDtor; //===----------------------------------------------------------------------===// // registerChecker //===----------------------------------------------------------------------===// /// \brief Used to register checkers. + /// + /// \returns a pointer to the checker object. template - void registerChecker() { + CHECKER *registerChecker() { + CheckerTag tag = getTag(); + CheckerRef &ref = CheckerTags[tag]; + if (ref) + return static_cast(ref); // already registered. + CHECKER *checker = new CHECKER(); CheckerDtors.push_back(CheckerDtor(checker, destruct)); CHECKER::_register(checker, *this); + ref = checker; + return checker; } //===----------------------------------------------------------------------===// @@ -179,6 +193,12 @@ public: const Stmt *S, ExprEngine &Eng); + /// \brief Run checkers for binding of a value to a location. + void runCheckersForBind(ExplodedNodeSet &Dst, + const ExplodedNodeSet &Src, + SVal location, SVal val, + const Stmt *S, ExprEngine &Eng); + /// \brief Run checkers for end of analysis. void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng); @@ -186,6 +206,10 @@ public: /// \brief Run checkers for end of path. void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng); + /// \brief Run checkers for branch condition. + void runCheckersForBranchCondition(const Stmt *condition, + BranchNodeBuilder &B, ExprEngine &Eng); + /// \brief Run checkers for live symbols. void runCheckersForLiveSymbols(const GRState *state, SymbolReaper &SymReaper); @@ -204,6 +228,10 @@ public: const MemRegion * const *Begin, const MemRegion * const *End); + /// \brief Run checkers for handling assumptions on symbolic values. + const GRState *runCheckersForEvalAssume(const GRState *state, + SVal Cond, bool Assumption); + /// \brief Run checkers for evaluating a call. void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, @@ -217,9 +245,8 @@ public: // Functions used by the registration mechanism, checkers should not touch // these directly. - typedef CheckerFn + typedef CheckerFn CheckDeclFunc; - typedef CheckerFn CheckStmtFunc; typedef bool (*HandlesDeclFunc)(const Decl *D); void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); @@ -230,14 +257,44 @@ public: // Internal registration functions for path-sensitive checking. //===----------------------------------------------------------------------===// - typedef CheckerFn CheckObjCMessageFunc; - typedef CheckerFn + typedef CheckerFn CheckStmtFunc; + + typedef CheckerFn + CheckObjCMessageFunc; + + typedef CheckerFn CheckLocationFunc; - typedef CheckerFn + + typedef CheckerFn CheckBindFunc; + + typedef CheckerFn CheckEndAnalysisFunc; - typedef CheckerFn CheckEndPathFunc; - typedef CheckerFn CheckDeadSymbolsFunc; - typedef CheckerFn CheckLiveSymbolsFunc; + + typedef CheckerFn + CheckEndPathFunc; + + typedef CheckerFn + CheckBranchConditionFunc; + + typedef CheckerFn + CheckDeadSymbolsFunc; + + typedef CheckerFn CheckLiveSymbolsFunc; + + typedef CheckerFn + CheckRegionChangesFunc; + + typedef CheckerFn WantsRegionChangeUpdateFunc; + + typedef CheckerFn + EvalAssumeFunc; + + typedef CheckerFn + EvalCallFunc; typedef bool (*HandlesStmtFunc)(const Stmt *D); void _registerForPreStmt(CheckStmtFunc checkfn, @@ -250,57 +307,54 @@ public: void _registerForLocation(CheckLocationFunc checkfn); + void _registerForBind(CheckBindFunc checkfn); + void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); void _registerForEndPath(CheckEndPathFunc checkfn); + void _registerForBranchCondition(CheckBranchConditionFunc checkfn); + void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); - class CheckRegionChangesFunc { - typedef const GRState * (*Func)(void *, const GRState *, - const MemRegion * const *, - const MemRegion * const *); - Func Fn; - public: - void *Checker; - CheckRegionChangesFunc(void *checker, Func fn) : Fn(fn), Checker(checker) {} - const GRState *operator()(const GRState *state, - const MemRegion * const *begin, - const MemRegion * const *end) { - return Fn(Checker, state, begin, end); - } - }; - - class WantsRegionChangeUpdateFunc { - typedef bool (*Func)(void *, const GRState *); - Func Fn; - public: - void *Checker; - WantsRegionChangeUpdateFunc(void *checker, Func fn) - : Fn(fn), Checker(checker) { } - bool operator()(const GRState *state) { - return Fn(Checker, state); - } - }; - void _registerForRegionChanges(CheckRegionChangesFunc checkfn, WantsRegionChangeUpdateFunc wantUpdateFn); - class EvalCallFunc { - typedef bool (*Func)(void *, const CallExpr *, CheckerContext &); - Func Fn; - public: - void *Checker; - EvalCallFunc(void *checker, Func fn) : Fn(fn), Checker(checker) { } - bool operator()(const CallExpr *CE, CheckerContext &C) { - return Fn(Checker, CE, C); - } - }; + void _registerForEvalAssume(EvalAssumeFunc checkfn); void _registerForEvalCall(EvalCallFunc checkfn); +//===----------------------------------------------------------------------===// +// Internal registration functions for events. +//===----------------------------------------------------------------------===// + + typedef void *EventTag; + typedef CheckerFn CheckEventFunc; + + template + void _registerListenerForEvent(CheckEventFunc checkfn) { + EventInfo &info = Events[getTag()]; + info.Checkers.push_back(checkfn); + } + + template + void _registerDispatcherForEvent() { + EventInfo &info = Events[getTag()]; + info.HasDispatcher = true; + } + + template + void _dispatchEvent(const EVENT &event) const { + EventsTy::const_iterator I = Events.find(getTag()); + if (I == Events.end()) + return; + const EventInfo &info = I->second; + for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) + info.Checkers[i](&event); + } + //===----------------------------------------------------------------------===// // Implementation details. //===----------------------------------------------------------------------===// @@ -309,6 +363,11 @@ private: template static void destruct(void *obj) { delete static_cast(obj); } + template + static void *getTag() { static int tag; return &tag; } + + llvm::DenseMap CheckerTags; + std::vector CheckerDtors; struct DeclCheckerInfo { @@ -365,10 +424,14 @@ private: std::vector LocationCheckers; + std::vector BindCheckers; + std::vector EndAnalysisCheckers; std::vector EndPathCheckers; + std::vector BranchConditionCheckers; + std::vector LiveSymbolsCheckers; std::vector DeadSymbolsCheckers; @@ -379,7 +442,18 @@ private: }; std::vector RegionChangesCheckers; + std::vector EvalAssumeCheckers; + std::vector EvalCallCheckers; + + struct EventInfo { + llvm::SmallVector Checkers; + bool HasDispatcher; + EventInfo() : HasDispatcher(false) { } + }; + + typedef llvm::DenseMap EventsTy; + EventsTy Events; }; } // end ento namespace -- cgit v1.2.3