]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/clang/StaticAnalyzer/Core/Checker.h
Vendor import of clang trunk r130700:
[FreeBSD/FreeBSD.git] / include / clang / StaticAnalyzer / Core / Checker.h
1 //== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines Checker, used to create and register checkers.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_SA_CORE_CHECKER
15 #define LLVM_CLANG_SA_CORE_CHECKER
16
17 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
19 #include "llvm/Support/Casting.h"
20
21 namespace clang {
22 namespace ento {
23   class BugReporter;
24
25 namespace check {
26
27 struct _VoidCheck {
28   static void _register(void *checker, CheckerManager &mgr) { }
29 };
30
31 template <typename DECL>
32 class ASTDecl {
33   template <typename CHECKER>
34   static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
35                          BugReporter &BR) {
36     ((const CHECKER *)checker)->checkASTDecl(llvm::cast<DECL>(D), mgr, BR);
37   }
38
39   static bool _handlesDecl(const Decl *D) {
40     return llvm::isa<DECL>(D);
41   }
42 public:
43   template <typename CHECKER>
44   static void _register(CHECKER *checker, CheckerManager &mgr) {
45     mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
46                                                        _checkDecl<CHECKER>),
47                          _handlesDecl);
48   }
49 };
50
51 class ASTCodeBody {
52   template <typename CHECKER>
53   static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
54                          BugReporter &BR) {
55     ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
56   }
57
58 public:
59   template <typename CHECKER>
60   static void _register(CHECKER *checker, CheckerManager &mgr) {
61     mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
62                                                        _checkBody<CHECKER>));
63   }
64 };
65
66 template <typename STMT>
67 class PreStmt {
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);
71   }
72
73   static bool _handlesStmt(const Stmt *S) {
74     return llvm::isa<STMT>(S);
75   }
76 public:
77   template <typename CHECKER>
78   static void _register(CHECKER *checker, CheckerManager &mgr) {
79     mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
80                                                           _checkStmt<CHECKER>),
81                             _handlesStmt);
82   }
83 };
84
85 template <typename STMT>
86 class PostStmt {
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);
90   }
91
92   static bool _handlesStmt(const Stmt *S) {
93     return llvm::isa<STMT>(S);
94   }
95 public:
96   template <typename CHECKER>
97   static void _register(CHECKER *checker, CheckerManager &mgr) {
98     mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
99                                                            _checkStmt<CHECKER>),
100                              _handlesStmt);
101   }
102 };
103
104 class PreObjCMessage {
105   template <typename CHECKER>
106   static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
107                                 CheckerContext &C) {
108     ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
109   }
110
111 public:
112   template <typename CHECKER>
113   static void _register(CHECKER *checker, CheckerManager &mgr) {
114     mgr._registerForPreObjCMessage(
115      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
116   }
117 };
118
119 class PostObjCMessage {
120   template <typename CHECKER>
121   static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
122                                 CheckerContext &C) {
123     ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
124   }
125
126 public:
127   template <typename CHECKER>
128   static void _register(CHECKER *checker, CheckerManager &mgr) {
129     mgr._registerForPostObjCMessage(
130      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
131   }
132 };
133
134 class Location {
135   template <typename CHECKER>
136   static void _checkLocation(void *checker, const SVal &location, bool isLoad,
137                              CheckerContext &C) {
138     ((const CHECKER *)checker)->checkLocation(location, isLoad, C);
139   }
140
141 public:
142   template <typename CHECKER>
143   static void _register(CHECKER *checker, CheckerManager &mgr) {
144     mgr._registerForLocation(
145            CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
146   }
147 };
148
149 class Bind {
150   template <typename CHECKER>
151   static void _checkBind(void *checker, const SVal &location, const SVal &val,
152                          CheckerContext &C) {
153     ((const CHECKER *)checker)->checkBind(location, val, C);
154   }
155
156 public:
157   template <typename CHECKER>
158   static void _register(CHECKER *checker, CheckerManager &mgr) {
159     mgr._registerForBind(
160            CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
161   }
162 };
163
164 class EndAnalysis {
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);
169   }
170
171 public:
172   template <typename CHECKER>
173   static void _register(CHECKER *checker, CheckerManager &mgr) {
174     mgr._registerForEndAnalysis(
175      CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
176   }
177 };
178
179 class EndPath {
180   template <typename CHECKER>
181   static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B,
182                             ExprEngine &Eng) {
183     ((const CHECKER *)checker)->checkEndPath(B, Eng);
184   }
185
186 public:
187   template <typename CHECKER>
188   static void _register(CHECKER *checker, CheckerManager &mgr) {
189     mgr._registerForEndPath(
190      CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
191   }
192 };
193
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);
199   }
200
201 public:
202   template <typename CHECKER>
203   static void _register(CHECKER *checker, CheckerManager &mgr) {
204     mgr._registerForBranchCondition(
205       CheckerManager::CheckBranchConditionFunc(checker,
206                                                _checkBranchCondition<CHECKER>));
207   }
208 };
209
210 class LiveSymbols {
211   template <typename CHECKER>
212   static void _checkLiveSymbols(void *checker, const GRState *state,
213                                 SymbolReaper &SR) {
214     ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
215   }
216
217 public:
218   template <typename CHECKER>
219   static void _register(CHECKER *checker, CheckerManager &mgr) {
220     mgr._registerForLiveSymbols(
221      CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
222   }
223 };
224
225 class DeadSymbols {
226   template <typename CHECKER>
227   static void _checkDeadSymbols(void *checker,
228                                 SymbolReaper &SR, CheckerContext &C) {
229     ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
230   }
231
232 public:
233   template <typename CHECKER>
234   static void _register(CHECKER *checker, CheckerManager &mgr) {
235     mgr._registerForDeadSymbols(
236      CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
237   }
238 };
239
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);
246   }
247   template <typename CHECKER>
248   static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) {
249     return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
250   }
251
252 public:
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>));
260   }
261 };
262
263 template <typename EVENT>
264 class Event {
265   template <typename CHECKER>
266   static void _checkEvent(void *checker, const void *event) {
267     ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
268   }
269 public:
270   template <typename CHECKER>
271   static void _register(CHECKER *checker, CheckerManager &mgr) {
272     mgr._registerListenerForEvent<EVENT>(
273                  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
274   }
275 };
276
277 } // end check namespace
278
279 namespace eval {
280
281 class Assume {
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);
286   }
287
288 public:
289   template <typename CHECKER>
290   static void _register(CHECKER *checker, CheckerManager &mgr) {
291     mgr._registerForEvalAssume(
292                  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
293   }
294 };
295
296 class Call {
297   template <typename CHECKER>
298   static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
299     return ((const CHECKER *)checker)->evalCall(CE, C);
300   }
301
302 public:
303   template <typename CHECKER>
304   static void _register(CHECKER *checker, CheckerManager &mgr) {
305     mgr._registerForEvalCall(
306                      CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
307   }
308 };
309
310 } // end eval namespace
311
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>
318 class Checker;
319
320 template <>
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> {
325 public:
326   static void _register(void *checker, CheckerManager &mgr) { }
327 };
328
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>
332 class Checker
333     : public CHECK1,
334       public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
335                        CHECK9, CHECK10, CHECK11, CHECK12> {
336 public:
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);
342   }
343 };
344
345 template <typename EVENT>
346 class EventDispatcher {
347   CheckerManager *Mgr;
348 public:
349   EventDispatcher() : Mgr(0) { }
350
351   template <typename CHECKER>
352   static void _register(CHECKER *checker, CheckerManager &mgr) {
353     mgr._registerDispatcherForEvent<EVENT>();
354     static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
355   }
356
357   void dispatchEvent(const EVENT &event) const {
358     Mgr->_dispatchEvent(event);
359   }
360 };
361
362 /// \brief We dereferenced a location that may be null.
363 struct ImplicitNullDerefEvent {
364   SVal Location;
365   bool IsLoad;
366   ExplodedNode *SinkNode;
367   BugReporter *BR;
368 };
369
370 } // end ento namespace
371
372 } // end clang namespace
373
374 #endif