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 template <typename STMT>
68 template <typename CHECKER>
69 static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
70 ((const CHECKER *)checker)->checkPreStmt(llvm::cast<STMT>(S), C);
73 static bool _handlesStmt(const Stmt *S) {
74 return llvm::isa<STMT>(S);
77 template <typename CHECKER>
78 static void _register(CHECKER *checker, CheckerManager &mgr) {
79 mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
85 template <typename STMT>
87 template <typename CHECKER>
88 static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
89 ((const CHECKER *)checker)->checkPostStmt(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._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
104 class PreObjCMessage {
105 template <typename CHECKER>
106 static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
108 ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
112 template <typename CHECKER>
113 static void _register(CHECKER *checker, CheckerManager &mgr) {
114 mgr._registerForPreObjCMessage(
115 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
119 class PostObjCMessage {
120 template <typename CHECKER>
121 static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
123 ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
127 template <typename CHECKER>
128 static void _register(CHECKER *checker, CheckerManager &mgr) {
129 mgr._registerForPostObjCMessage(
130 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
135 template <typename CHECKER>
136 static void _checkLocation(void *checker, const SVal &location, bool isLoad,
138 ((const CHECKER *)checker)->checkLocation(location, isLoad, C);
142 template <typename CHECKER>
143 static void _register(CHECKER *checker, CheckerManager &mgr) {
144 mgr._registerForLocation(
145 CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
150 template <typename CHECKER>
151 static void _checkBind(void *checker, const SVal &location, const SVal &val,
153 ((const CHECKER *)checker)->checkBind(location, val, C);
157 template <typename CHECKER>
158 static void _register(CHECKER *checker, CheckerManager &mgr) {
159 mgr._registerForBind(
160 CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
165 template <typename CHECKER>
166 static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
167 BugReporter &BR, ExprEngine &Eng) {
168 ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
172 template <typename CHECKER>
173 static void _register(CHECKER *checker, CheckerManager &mgr) {
174 mgr._registerForEndAnalysis(
175 CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
180 template <typename CHECKER>
181 static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B,
183 ((const CHECKER *)checker)->checkEndPath(B, Eng);
187 template <typename CHECKER>
188 static void _register(CHECKER *checker, CheckerManager &mgr) {
189 mgr._registerForEndPath(
190 CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
194 class BranchCondition {
195 template <typename CHECKER>
196 static void _checkBranchCondition(void *checker, const Stmt *condition,
197 BranchNodeBuilder &B, ExprEngine &Eng) {
198 ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
202 template <typename CHECKER>
203 static void _register(CHECKER *checker, CheckerManager &mgr) {
204 mgr._registerForBranchCondition(
205 CheckerManager::CheckBranchConditionFunc(checker,
206 _checkBranchCondition<CHECKER>));
211 template <typename CHECKER>
212 static void _checkLiveSymbols(void *checker, const GRState *state,
214 ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
218 template <typename CHECKER>
219 static void _register(CHECKER *checker, CheckerManager &mgr) {
220 mgr._registerForLiveSymbols(
221 CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
226 template <typename CHECKER>
227 static void _checkDeadSymbols(void *checker,
228 SymbolReaper &SR, CheckerContext &C) {
229 ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
233 template <typename CHECKER>
234 static void _register(CHECKER *checker, CheckerManager &mgr) {
235 mgr._registerForDeadSymbols(
236 CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
240 class RegionChanges {
241 template <typename CHECKER>
242 static const GRState *_checkRegionChanges(void *checker, const GRState *state,
243 const MemRegion * const *Begin,
244 const MemRegion * const *End) {
245 return ((const CHECKER *)checker)->checkRegionChanges(state, Begin, End);
247 template <typename CHECKER>
248 static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) {
249 return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
253 template <typename CHECKER>
254 static void _register(CHECKER *checker, CheckerManager &mgr) {
255 mgr._registerForRegionChanges(
256 CheckerManager::CheckRegionChangesFunc(checker,
257 _checkRegionChanges<CHECKER>),
258 CheckerManager::WantsRegionChangeUpdateFunc(checker,
259 _wantsRegionChangeUpdate<CHECKER>));
263 template <typename EVENT>
265 template <typename CHECKER>
266 static void _checkEvent(void *checker, const void *event) {
267 ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
270 template <typename CHECKER>
271 static void _register(CHECKER *checker, CheckerManager &mgr) {
272 mgr._registerListenerForEvent<EVENT>(
273 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
277 } // end check namespace
282 template <typename CHECKER>
283 static const GRState *_evalAssume(void *checker, const GRState *state,
284 const SVal &cond, bool assumption) {
285 return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
289 template <typename CHECKER>
290 static void _register(CHECKER *checker, CheckerManager &mgr) {
291 mgr._registerForEvalAssume(
292 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
297 template <typename CHECKER>
298 static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
299 return ((const CHECKER *)checker)->evalCall(CE, C);
303 template <typename CHECKER>
304 static void _register(CHECKER *checker, CheckerManager &mgr) {
305 mgr._registerForEvalCall(
306 CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
310 } // end eval namespace
312 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
313 typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
314 typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
315 typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
316 typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
317 typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck>
321 class Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
322 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
323 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
324 check::_VoidCheck, check::_VoidCheck, check::_VoidCheck> {
326 static void _register(void *checker, CheckerManager &mgr) { }
329 template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
330 typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
331 typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12>
334 public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
335 CHECK9, CHECK10, CHECK11, CHECK12> {
337 template <typename CHECKER>
338 static void _register(CHECKER *checker, CheckerManager &mgr) {
339 CHECK1::_register(checker, mgr);
340 Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, CHECK9,
341 CHECK10, CHECK11,CHECK12>::_register(checker, mgr);
345 template <typename EVENT>
346 class EventDispatcher {
349 EventDispatcher() : Mgr(0) { }
351 template <typename CHECKER>
352 static void _register(CHECKER *checker, CheckerManager &mgr) {
353 mgr._registerDispatcherForEvent<EVENT>();
354 static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
357 void dispatchEvent(const EVENT &event) const {
358 Mgr->_dispatchEvent(event);
362 /// \brief We dereferenced a location that may be null.
363 struct ImplicitNullDerefEvent {
366 ExplodedNode *SinkNode;
370 } // end ento namespace
372 } // end clang namespace