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/Analysis/ProgramPoint.h"
18 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
20 #include "llvm/Support/Casting.h"
29 static void _register(void *checker, CheckerManager &mgr) { }
32 template <typename DECL>
34 template <typename CHECKER>
35 static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
37 ((const CHECKER *)checker)->checkASTDecl(llvm::cast<DECL>(D), mgr, BR);
40 static bool _handlesDecl(const Decl *D) {
41 return llvm::isa<DECL>(D);
44 template <typename CHECKER>
45 static void _register(CHECKER *checker, CheckerManager &mgr) {
46 mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
53 template <typename CHECKER>
54 static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
56 ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
60 template <typename CHECKER>
61 static void _register(CHECKER *checker, CheckerManager &mgr) {
62 mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
63 _checkBody<CHECKER>));
67 class EndOfTranslationUnit {
68 template <typename CHECKER>
69 static void _checkEndOfTranslationUnit(void *checker,
70 const TranslationUnitDecl *TU,
73 ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
77 template <typename CHECKER>
78 static void _register(CHECKER *checker, CheckerManager &mgr){
79 mgr._registerForEndOfTranslationUnit(
80 CheckerManager::CheckEndOfTranslationUnit(checker,
81 _checkEndOfTranslationUnit<CHECKER>));
85 template <typename STMT>
87 template <typename CHECKER>
88 static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
89 ((const CHECKER *)checker)->checkPreStmt(llvm::cast<STMT>(S), C);
92 static bool _handlesStmt(const Stmt *S) {
93 return llvm::isa<STMT>(S);
96 template <typename CHECKER>
97 static void _register(CHECKER *checker, CheckerManager &mgr) {
98 mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
104 template <typename STMT>
106 template <typename CHECKER>
107 static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
108 ((const CHECKER *)checker)->checkPostStmt(llvm::cast<STMT>(S), C);
111 static bool _handlesStmt(const Stmt *S) {
112 return llvm::isa<STMT>(S);
115 template <typename CHECKER>
116 static void _register(CHECKER *checker, CheckerManager &mgr) {
117 mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
118 _checkStmt<CHECKER>),
123 class PreObjCMessage {
124 template <typename CHECKER>
125 static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
127 ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
131 template <typename CHECKER>
132 static void _register(CHECKER *checker, CheckerManager &mgr) {
133 mgr._registerForPreObjCMessage(
134 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
138 class PostObjCMessage {
139 template <typename CHECKER>
140 static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
142 ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
146 template <typename CHECKER>
147 static void _register(CHECKER *checker, CheckerManager &mgr) {
148 mgr._registerForPostObjCMessage(
149 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
154 template <typename CHECKER>
155 static void _checkLocation(void *checker,
156 const SVal &location, bool isLoad, const Stmt *S,
158 ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
162 template <typename CHECKER>
163 static void _register(CHECKER *checker, CheckerManager &mgr) {
164 mgr._registerForLocation(
165 CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
170 template <typename CHECKER>
171 static void _checkBind(void *checker,
172 const SVal &location, const SVal &val, const Stmt *S,
174 ((const CHECKER *)checker)->checkBind(location, val, S, C);
178 template <typename CHECKER>
179 static void _register(CHECKER *checker, CheckerManager &mgr) {
180 mgr._registerForBind(
181 CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
186 template <typename CHECKER>
187 static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
188 BugReporter &BR, ExprEngine &Eng) {
189 ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
193 template <typename CHECKER>
194 static void _register(CHECKER *checker, CheckerManager &mgr) {
195 mgr._registerForEndAnalysis(
196 CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
201 template <typename CHECKER>
202 static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B,
204 ((const CHECKER *)checker)->checkEndPath(B, Eng);
208 template <typename CHECKER>
209 static void _register(CHECKER *checker, CheckerManager &mgr) {
210 mgr._registerForEndPath(
211 CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
215 class BranchCondition {
216 template <typename CHECKER>
217 static void _checkBranchCondition(void *checker, const Stmt *condition,
218 BranchNodeBuilder &B, ExprEngine &Eng) {
219 ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
223 template <typename CHECKER>
224 static void _register(CHECKER *checker, CheckerManager &mgr) {
225 mgr._registerForBranchCondition(
226 CheckerManager::CheckBranchConditionFunc(checker,
227 _checkBranchCondition<CHECKER>));
232 template <typename CHECKER>
233 static void _checkLiveSymbols(void *checker, const ProgramState *state,
235 ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
239 template <typename CHECKER>
240 static void _register(CHECKER *checker, CheckerManager &mgr) {
241 mgr._registerForLiveSymbols(
242 CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
247 template <typename CHECKER>
248 static void _checkDeadSymbols(void *checker,
249 SymbolReaper &SR, CheckerContext &C) {
250 ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
254 template <typename CHECKER>
255 static void _register(CHECKER *checker, CheckerManager &mgr) {
256 mgr._registerForDeadSymbols(
257 CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
261 class RegionChanges {
262 template <typename CHECKER>
263 static const ProgramState *
264 _checkRegionChanges(void *checker,
265 const ProgramState *state,
266 const StoreManager::InvalidatedSymbols *invalidated,
267 ArrayRef<const MemRegion *> Explicits,
268 ArrayRef<const MemRegion *> Regions) {
269 return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
272 template <typename CHECKER>
273 static bool _wantsRegionChangeUpdate(void *checker,
274 const ProgramState *state) {
275 return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
279 template <typename CHECKER>
280 static void _register(CHECKER *checker, CheckerManager &mgr) {
281 mgr._registerForRegionChanges(
282 CheckerManager::CheckRegionChangesFunc(checker,
283 _checkRegionChanges<CHECKER>),
284 CheckerManager::WantsRegionChangeUpdateFunc(checker,
285 _wantsRegionChangeUpdate<CHECKER>));
289 template <typename EVENT>
291 template <typename CHECKER>
292 static void _checkEvent(void *checker, const void *event) {
293 ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
296 template <typename CHECKER>
297 static void _register(CHECKER *checker, CheckerManager &mgr) {
298 mgr._registerListenerForEvent<EVENT>(
299 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
303 } // end check namespace
308 template <typename CHECKER>
309 static const ProgramState *_evalAssume(void *checker,
310 const ProgramState *state,
313 return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
317 template <typename CHECKER>
318 static void _register(CHECKER *checker, CheckerManager &mgr) {
319 mgr._registerForEvalAssume(
320 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
325 template <typename CHECKER>
326 static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
327 return ((const CHECKER *)checker)->evalCall(CE, C);
331 template <typename CHECKER>
332 static void _register(CHECKER *checker, CheckerManager &mgr) {
333 mgr._registerForEvalCall(
334 CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
339 template <typename CHECKER>
340 static bool _inlineCall(void *checker, const CallExpr *CE,
343 ExplodedNodeSet &Dst) {
344 return ((const CHECKER *)checker)->inlineCall(CE, Eng, Pred, Dst);
348 template <typename CHECKER>
349 static void _register(CHECKER *checker, CheckerManager &mgr) {
350 mgr._registerForInlineCall(
351 CheckerManager::InlineCallFunc(checker, _inlineCall<CHECKER>));
355 } // end eval namespace
357 class CheckerBase : public ProgramPointTag {
359 StringRef getTagDescription() const;
361 /// See CheckerManager::runCheckersForPrintState.
362 virtual void printState(raw_ostream &Out, const ProgramState *State,
363 const char *NL, const char *Sep) const { }
366 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
367 typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
368 typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
369 typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
370 typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
371 typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck,
372 typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck,
373 typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck>
377 class Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
378 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
379 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
380 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
381 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
386 static void _register(void *checker, CheckerManager &mgr) { }
389 template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
390 typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
391 typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12,
392 typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16>
395 public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
396 CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,CHECK14,CHECK15,
399 template <typename CHECKER>
400 static void _register(CHECKER *checker, CheckerManager &mgr) {
401 CHECK1::_register(checker, mgr);
402 Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
403 CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,CHECK14,CHECK15,
404 CHECK16>::_register(checker, mgr);
408 template <typename EVENT>
409 class EventDispatcher {
412 EventDispatcher() : Mgr(0) { }
414 template <typename CHECKER>
415 static void _register(CHECKER *checker, CheckerManager &mgr) {
416 mgr._registerDispatcherForEvent<EVENT>();
417 static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
420 void dispatchEvent(const EVENT &event) const {
421 Mgr->_dispatchEvent(event);
425 /// \brief We dereferenced a location that may be null.
426 struct ImplicitNullDerefEvent {
429 ExplodedNode *SinkNode;
433 } // end ento namespace
435 } // end clang namespace