1 //== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines Checker, used to create and register checkers.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SA_CORE_CHECKER
15 #define LLVM_CLANG_SA_CORE_CHECKER
17 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
19 #include "llvm/Support/Casting.h"
28 static void _register(void *checker, CheckerManager &mgr) { }
31 template <typename DECL>
33 template <typename CHECKER>
34 static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
36 ((const CHECKER *)checker)->checkASTDecl(llvm::cast<DECL>(D), mgr, BR);
39 static bool _handlesDecl(const Decl *D) {
40 return llvm::isa<DECL>(D);
43 template <typename CHECKER>
44 static void _register(CHECKER *checker, CheckerManager &mgr) {
45 mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
52 template <typename CHECKER>
53 static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
55 ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
59 template <typename CHECKER>
60 static void _register(CHECKER *checker, CheckerManager &mgr) {
61 mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
62 _checkBody<CHECKER>));
66 class EndOfTranslationUnit {
67 template <typename CHECKER>
68 static void _checkEndOfTranslationUnit(void *checker,
69 const TranslationUnitDecl *TU,
72 ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
76 template <typename CHECKER>
77 static void _register(CHECKER *checker, CheckerManager &mgr){
78 mgr._registerForEndOfTranslationUnit(
79 CheckerManager::CheckEndOfTranslationUnit(checker,
80 _checkEndOfTranslationUnit<CHECKER>));
84 template <typename STMT>
86 template <typename CHECKER>
87 static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
88 ((const CHECKER *)checker)->checkPreStmt(llvm::cast<STMT>(S), C);
91 static bool _handlesStmt(const Stmt *S) {
92 return llvm::isa<STMT>(S);
95 template <typename CHECKER>
96 static void _register(CHECKER *checker, CheckerManager &mgr) {
97 mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
103 template <typename STMT>
105 template <typename CHECKER>
106 static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
107 ((const CHECKER *)checker)->checkPostStmt(llvm::cast<STMT>(S), C);
110 static bool _handlesStmt(const Stmt *S) {
111 return llvm::isa<STMT>(S);
114 template <typename CHECKER>
115 static void _register(CHECKER *checker, CheckerManager &mgr) {
116 mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
117 _checkStmt<CHECKER>),
122 class PreObjCMessage {
123 template <typename CHECKER>
124 static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
126 ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
130 template <typename CHECKER>
131 static void _register(CHECKER *checker, CheckerManager &mgr) {
132 mgr._registerForPreObjCMessage(
133 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
137 class PostObjCMessage {
138 template <typename CHECKER>
139 static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
141 ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
145 template <typename CHECKER>
146 static void _register(CHECKER *checker, CheckerManager &mgr) {
147 mgr._registerForPostObjCMessage(
148 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
153 template <typename CHECKER>
154 static void _checkLocation(void *checker, const SVal &location, bool isLoad,
156 ((const CHECKER *)checker)->checkLocation(location, isLoad, C);
160 template <typename CHECKER>
161 static void _register(CHECKER *checker, CheckerManager &mgr) {
162 mgr._registerForLocation(
163 CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
168 template <typename CHECKER>
169 static void _checkBind(void *checker, const SVal &location, const SVal &val,
171 ((const CHECKER *)checker)->checkBind(location, val, C);
175 template <typename CHECKER>
176 static void _register(CHECKER *checker, CheckerManager &mgr) {
177 mgr._registerForBind(
178 CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
183 template <typename CHECKER>
184 static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
185 BugReporter &BR, ExprEngine &Eng) {
186 ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
190 template <typename CHECKER>
191 static void _register(CHECKER *checker, CheckerManager &mgr) {
192 mgr._registerForEndAnalysis(
193 CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
198 template <typename CHECKER>
199 static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B,
201 ((const CHECKER *)checker)->checkEndPath(B, Eng);
205 template <typename CHECKER>
206 static void _register(CHECKER *checker, CheckerManager &mgr) {
207 mgr._registerForEndPath(
208 CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
212 class BranchCondition {
213 template <typename CHECKER>
214 static void _checkBranchCondition(void *checker, const Stmt *condition,
215 BranchNodeBuilder &B, ExprEngine &Eng) {
216 ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
220 template <typename CHECKER>
221 static void _register(CHECKER *checker, CheckerManager &mgr) {
222 mgr._registerForBranchCondition(
223 CheckerManager::CheckBranchConditionFunc(checker,
224 _checkBranchCondition<CHECKER>));
229 template <typename CHECKER>
230 static void _checkLiveSymbols(void *checker, const GRState *state,
232 ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
236 template <typename CHECKER>
237 static void _register(CHECKER *checker, CheckerManager &mgr) {
238 mgr._registerForLiveSymbols(
239 CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
244 template <typename CHECKER>
245 static void _checkDeadSymbols(void *checker,
246 SymbolReaper &SR, CheckerContext &C) {
247 ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
251 template <typename CHECKER>
252 static void _register(CHECKER *checker, CheckerManager &mgr) {
253 mgr._registerForDeadSymbols(
254 CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
258 class RegionChanges {
259 template <typename CHECKER>
260 static const GRState *_checkRegionChanges(void *checker, const GRState *state,
261 const StoreManager::InvalidatedSymbols *invalidated,
262 const MemRegion * const *Begin,
263 const MemRegion * const *End) {
264 return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
267 template <typename CHECKER>
268 static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) {
269 return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
273 template <typename CHECKER>
274 static void _register(CHECKER *checker, CheckerManager &mgr) {
275 mgr._registerForRegionChanges(
276 CheckerManager::CheckRegionChangesFunc(checker,
277 _checkRegionChanges<CHECKER>),
278 CheckerManager::WantsRegionChangeUpdateFunc(checker,
279 _wantsRegionChangeUpdate<CHECKER>));
283 template <typename EVENT>
285 template <typename CHECKER>
286 static void _checkEvent(void *checker, const void *event) {
287 ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
290 template <typename CHECKER>
291 static void _register(CHECKER *checker, CheckerManager &mgr) {
292 mgr._registerListenerForEvent<EVENT>(
293 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
297 } // end check namespace
302 template <typename CHECKER>
303 static const GRState *_evalAssume(void *checker, const GRState *state,
304 const SVal &cond, bool assumption) {
305 return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
309 template <typename CHECKER>
310 static void _register(CHECKER *checker, CheckerManager &mgr) {
311 mgr._registerForEvalAssume(
312 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
317 template <typename CHECKER>
318 static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
319 return ((const CHECKER *)checker)->evalCall(CE, C);
323 template <typename CHECKER>
324 static void _register(CHECKER *checker, CheckerManager &mgr) {
325 mgr._registerForEvalCall(
326 CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
330 } // end eval namespace
332 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
333 typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
334 typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
335 typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
336 typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
337 typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck>
341 class Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
342 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
343 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
344 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck> {
346 static void _register(void *checker, CheckerManager &mgr) { }
349 template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
350 typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
351 typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12>
354 public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
355 CHECK9, CHECK10, CHECK11, CHECK12> {
357 template <typename CHECKER>
358 static void _register(CHECKER *checker, CheckerManager &mgr) {
359 CHECK1::_register(checker, mgr);
360 Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, CHECK9,
361 CHECK10, CHECK11,CHECK12>::_register(checker, mgr);
365 template <typename EVENT>
366 class EventDispatcher {
369 EventDispatcher() : Mgr(0) { }
371 template <typename CHECKER>
372 static void _register(CHECKER *checker, CheckerManager &mgr) {
373 mgr._registerDispatcherForEvent<EVENT>();
374 static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
377 void dispatchEvent(const EVENT &event) const {
378 Mgr->_dispatchEvent(event);
382 /// \brief We dereferenced a location that may be null.
383 struct ImplicitNullDerefEvent {
386 ExplodedNode *SinkNode;
390 } // end ento namespace
392 } // end clang namespace