//== Checker.h - Registration mechanism 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, used to create and register checkers. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_SA_CORE_CHECKER #define LLVM_CLANG_SA_CORE_CHECKER #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/Support/Casting.h" namespace clang { namespace ento { class BugReporter; namespace check { struct _VoidCheck { static void _register(void *checker, CheckerManager &mgr) { } }; template class ASTDecl { template static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkASTDecl(llvm::cast(D), mgr, BR); } static bool _handlesDecl(const Decl *D) { return llvm::isa(D); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker, _checkDecl), _handlesDecl); } }; class ASTCodeBody { template static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForBody(CheckerManager::CheckDeclFunc(checker, _checkBody)); } }; class EndOfTranslationUnit { template static void _checkEndOfTranslationUnit(void *checker, const TranslationUnitDecl *TU, AnalysisManager& mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR); } public: template static void _register(CHECKER *checker, CheckerManager &mgr){ mgr._registerForEndOfTranslationUnit( CheckerManager::CheckEndOfTranslationUnit(checker, _checkEndOfTranslationUnit)); } }; template class PreStmt { template static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { ((const CHECKER *)checker)->checkPreStmt(llvm::cast(S), C); } static bool _handlesStmt(const Stmt *S) { return llvm::isa(S); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker, _checkStmt), _handlesStmt); } }; template class PostStmt { template static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { ((const CHECKER *)checker)->checkPostStmt(llvm::cast(S), C); } static bool _handlesStmt(const Stmt *S) { return llvm::isa(S); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker, _checkStmt), _handlesStmt); } }; class PreObjCMessage { template static void _checkObjCMessage(void *checker, const ObjCMessage &msg, CheckerContext &C) { ((const CHECKER *)checker)->checkPreObjCMessage(msg, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForPreObjCMessage( CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage)); } }; class PostObjCMessage { template static void _checkObjCMessage(void *checker, const ObjCMessage &msg, CheckerContext &C) { ((const CHECKER *)checker)->checkPostObjCMessage(msg, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForPostObjCMessage( CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage)); } }; class Location { template static void _checkLocation(void *checker, const SVal &location, bool isLoad, CheckerContext &C) { ((const CHECKER *)checker)->checkLocation(location, isLoad, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForLocation( CheckerManager::CheckLocationFunc(checker, _checkLocation)); } }; class Bind { template static void _checkBind(void *checker, const SVal &location, const SVal &val, CheckerContext &C) { ((const CHECKER *)checker)->checkBind(location, val, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForBind( CheckerManager::CheckBindFunc(checker, _checkBind)); } }; class EndAnalysis { template static void _checkEndAnalysis(void *checker, ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng) { ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEndAnalysis( CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis)); } }; class EndPath { template static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B, ExprEngine &Eng) { ((const CHECKER *)checker)->checkEndPath(B, Eng); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEndPath( CheckerManager::CheckEndPathFunc(checker, _checkEndPath)); } }; class BranchCondition { template static void _checkBranchCondition(void *checker, const Stmt *condition, BranchNodeBuilder &B, ExprEngine &Eng) { ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForBranchCondition( CheckerManager::CheckBranchConditionFunc(checker, _checkBranchCondition)); } }; class LiveSymbols { template static void _checkLiveSymbols(void *checker, const GRState *state, SymbolReaper &SR) { ((const CHECKER *)checker)->checkLiveSymbols(state, SR); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForLiveSymbols( CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols)); } }; class DeadSymbols { template static void _checkDeadSymbols(void *checker, SymbolReaper &SR, CheckerContext &C) { ((const CHECKER *)checker)->checkDeadSymbols(SR, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForDeadSymbols( CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols)); } }; class RegionChanges { template static const GRState *_checkRegionChanges(void *checker, const GRState *state, const StoreManager::InvalidatedSymbols *invalidated, const MemRegion * const *Begin, const MemRegion * const *End) { return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated, Begin, End); } template static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) { return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForRegionChanges( CheckerManager::CheckRegionChangesFunc(checker, _checkRegionChanges), CheckerManager::WantsRegionChangeUpdateFunc(checker, _wantsRegionChangeUpdate)); } }; template class Event { template static void _checkEvent(void *checker, const void *event) { ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerListenerForEvent( CheckerManager::CheckEventFunc(checker, _checkEvent)); } }; } // end check namespace namespace eval { class Assume { template static const GRState *_evalAssume(void *checker, const GRState *state, const SVal &cond, bool assumption) { return ((const CHECKER *)checker)->evalAssume(state, cond, assumption); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEvalAssume( CheckerManager::EvalAssumeFunc(checker, _evalAssume)); } }; class Call { template static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) { return ((const CHECKER *)checker)->evalCall(CE, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEvalCall( CheckerManager::EvalCallFunc(checker, _evalCall)); } }; } // end eval namespace template class Checker; template <> class Checker { public: static void _register(void *checker, CheckerManager &mgr) { } }; template class Checker : public CHECK1, public Checker { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { CHECK1::_register(checker, mgr); Checker::_register(checker, mgr); } }; template class EventDispatcher { CheckerManager *Mgr; public: EventDispatcher() : Mgr(0) { } template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerDispatcherForEvent(); static_cast *>(checker)->Mgr = &mgr; } void dispatchEvent(const EVENT &event) const { Mgr->_dispatchEvent(event); } }; /// \brief We dereferenced a location that may be null. struct ImplicitNullDerefEvent { SVal Location; bool IsLoad; ExplodedNode *SinkNode; BugReporter *BR; }; } // end ento namespace } // end clang namespace #endif