]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h
Upgrade our copy of llvm/clang to trunk r162107. With thanks to
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / 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/Analysis/ProgramPoint.h"
18 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
20 #include "llvm/Support/Casting.h"
21
22 namespace clang {
23 namespace ento {
24   class BugReporter;
25
26 namespace check {
27
28 struct _VoidCheck {
29   static void _register(void *checker, CheckerManager &mgr) { }
30 };
31
32 template <typename DECL>
33 class ASTDecl {
34   template <typename CHECKER>
35   static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
36                          BugReporter &BR) {
37     ((const CHECKER *)checker)->checkASTDecl(llvm::cast<DECL>(D), mgr, BR);
38   }
39
40   static bool _handlesDecl(const Decl *D) {
41     return llvm::isa<DECL>(D);
42   }
43 public:
44   template <typename CHECKER>
45   static void _register(CHECKER *checker, CheckerManager &mgr) {
46     mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
47                                                        _checkDecl<CHECKER>),
48                          _handlesDecl);
49   }
50 };
51
52 class ASTCodeBody {
53   template <typename CHECKER>
54   static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
55                          BugReporter &BR) {
56     ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
57   }
58
59 public:
60   template <typename CHECKER>
61   static void _register(CHECKER *checker, CheckerManager &mgr) {
62     mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
63                                                        _checkBody<CHECKER>));
64   }
65 };
66
67 class EndOfTranslationUnit {
68   template <typename CHECKER>
69   static void _checkEndOfTranslationUnit(void *checker,
70                                          const TranslationUnitDecl *TU, 
71                                          AnalysisManager& mgr,
72                                          BugReporter &BR) {
73     ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
74   }
75
76 public:
77   template <typename CHECKER>
78   static void _register(CHECKER *checker, CheckerManager &mgr){
79     mgr._registerForEndOfTranslationUnit(
80                               CheckerManager::CheckEndOfTranslationUnit(checker,
81                                           _checkEndOfTranslationUnit<CHECKER>));
82   }
83 };
84
85 template <typename STMT>
86 class PreStmt {
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);
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._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
99                                                           _checkStmt<CHECKER>),
100                             _handlesStmt);
101   }
102 };
103
104 template <typename STMT>
105 class PostStmt {
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);
109   }
110
111   static bool _handlesStmt(const Stmt *S) {
112     return llvm::isa<STMT>(S);
113   }
114 public:
115   template <typename CHECKER>
116   static void _register(CHECKER *checker, CheckerManager &mgr) {
117     mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
118                                                            _checkStmt<CHECKER>),
119                              _handlesStmt);
120   }
121 };
122
123 class PreObjCMessage {
124   template <typename CHECKER>
125   static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
126                                 CheckerContext &C) {
127     ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
128   }
129
130 public:
131   template <typename CHECKER>
132   static void _register(CHECKER *checker, CheckerManager &mgr) {
133     mgr._registerForPreObjCMessage(
134      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
135   }
136 };
137
138 class PostObjCMessage {
139   template <typename CHECKER>
140   static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
141                                 CheckerContext &C) {
142     ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
143   }
144
145 public:
146   template <typename CHECKER>
147   static void _register(CHECKER *checker, CheckerManager &mgr) {
148     mgr._registerForPostObjCMessage(
149      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
150   }
151 };
152
153 class PreCall {
154   template <typename CHECKER>
155   static void _checkCall(void *checker, const CallEvent &msg,
156                          CheckerContext &C) {
157     ((const CHECKER *)checker)->checkPreCall(msg, C);
158   }
159
160 public:
161   template <typename CHECKER>
162   static void _register(CHECKER *checker, CheckerManager &mgr) {
163     mgr._registerForPreCall(
164      CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
165   }
166 };
167
168 class PostCall {
169   template <typename CHECKER>
170   static void _checkCall(void *checker, const CallEvent &msg,
171                          CheckerContext &C) {
172     ((const CHECKER *)checker)->checkPostCall(msg, C);
173   }
174
175 public:
176   template <typename CHECKER>
177   static void _register(CHECKER *checker, CheckerManager &mgr) {
178     mgr._registerForPostCall(
179      CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
180   }
181 };
182
183 class Location {
184   template <typename CHECKER>
185   static void _checkLocation(void *checker,
186                              const SVal &location, bool isLoad, const Stmt *S,
187                              CheckerContext &C) {
188     ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
189   }
190
191 public:
192   template <typename CHECKER>
193   static void _register(CHECKER *checker, CheckerManager &mgr) {
194     mgr._registerForLocation(
195            CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
196   }
197 };
198
199 class Bind {
200   template <typename CHECKER>
201   static void _checkBind(void *checker,
202                          const SVal &location, const SVal &val, const Stmt *S,
203                          CheckerContext &C) {
204     ((const CHECKER *)checker)->checkBind(location, val, S, C);
205   }
206
207 public:
208   template <typename CHECKER>
209   static void _register(CHECKER *checker, CheckerManager &mgr) {
210     mgr._registerForBind(
211            CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
212   }
213 };
214
215 class EndAnalysis {
216   template <typename CHECKER>
217   static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
218                                 BugReporter &BR, ExprEngine &Eng) {
219     ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
220   }
221
222 public:
223   template <typename CHECKER>
224   static void _register(CHECKER *checker, CheckerManager &mgr) {
225     mgr._registerForEndAnalysis(
226      CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
227   }
228 };
229
230 class EndPath {
231   template <typename CHECKER>
232   static void _checkEndPath(void *checker,
233                             CheckerContext &C) {
234     ((const CHECKER *)checker)->checkEndPath(C);
235   }
236
237 public:
238   template <typename CHECKER>
239   static void _register(CHECKER *checker, CheckerManager &mgr) {
240     mgr._registerForEndPath(
241      CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>));
242   }
243 };
244
245 class BranchCondition {
246   template <typename CHECKER>
247   static void _checkBranchCondition(void *checker, const Stmt *Condition,
248                                     CheckerContext & C) {
249     ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
250   }
251
252 public:
253   template <typename CHECKER>
254   static void _register(CHECKER *checker, CheckerManager &mgr) {
255     mgr._registerForBranchCondition(
256       CheckerManager::CheckBranchConditionFunc(checker,
257                                                _checkBranchCondition<CHECKER>));
258   }
259 };
260
261 class LiveSymbols {
262   template <typename CHECKER>
263   static void _checkLiveSymbols(void *checker, ProgramStateRef state,
264                                 SymbolReaper &SR) {
265     ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
266   }
267
268 public:
269   template <typename CHECKER>
270   static void _register(CHECKER *checker, CheckerManager &mgr) {
271     mgr._registerForLiveSymbols(
272      CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
273   }
274 };
275
276 class DeadSymbols {
277   template <typename CHECKER>
278   static void _checkDeadSymbols(void *checker,
279                                 SymbolReaper &SR, CheckerContext &C) {
280     ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
281   }
282
283 public:
284   template <typename CHECKER>
285   static void _register(CHECKER *checker, CheckerManager &mgr) {
286     mgr._registerForDeadSymbols(
287      CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
288   }
289 };
290
291 class RegionChanges {
292   template <typename CHECKER>
293   static ProgramStateRef 
294   _checkRegionChanges(void *checker,
295                       ProgramStateRef state,
296                       const StoreManager::InvalidatedSymbols *invalidated,
297                       ArrayRef<const MemRegion *> Explicits,
298                       ArrayRef<const MemRegion *> Regions,
299                       const CallEvent *Call) {
300     return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
301                                                       Explicits, Regions, Call);
302   }
303   template <typename CHECKER>
304   static bool _wantsRegionChangeUpdate(void *checker,
305                                        ProgramStateRef state) {
306     return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
307   }
308
309 public:
310   template <typename CHECKER>
311   static void _register(CHECKER *checker, CheckerManager &mgr) {
312     mgr._registerForRegionChanges(
313           CheckerManager::CheckRegionChangesFunc(checker,
314                                                  _checkRegionChanges<CHECKER>),
315           CheckerManager::WantsRegionChangeUpdateFunc(checker,
316                                             _wantsRegionChangeUpdate<CHECKER>));
317   }
318 };
319
320 template <typename EVENT>
321 class Event {
322   template <typename CHECKER>
323   static void _checkEvent(void *checker, const void *event) {
324     ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
325   }
326 public:
327   template <typename CHECKER>
328   static void _register(CHECKER *checker, CheckerManager &mgr) {
329     mgr._registerListenerForEvent<EVENT>(
330                  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
331   }
332 };
333
334 } // end check namespace
335
336 namespace eval {
337
338 class Assume {
339   template <typename CHECKER>
340   static ProgramStateRef _evalAssume(void *checker,
341                                          ProgramStateRef state,
342                                          const SVal &cond,
343                                          bool assumption) {
344     return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
345   }
346
347 public:
348   template <typename CHECKER>
349   static void _register(CHECKER *checker, CheckerManager &mgr) {
350     mgr._registerForEvalAssume(
351                  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
352   }
353 };
354
355 class Call {
356   template <typename CHECKER>
357   static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
358     return ((const CHECKER *)checker)->evalCall(CE, C);
359   }
360
361 public:
362   template <typename CHECKER>
363   static void _register(CHECKER *checker, CheckerManager &mgr) {
364     mgr._registerForEvalCall(
365                      CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
366   }
367 };
368
369 class InlineCall {
370   template <typename CHECKER>
371   static bool _inlineCall(void *checker, const CallExpr *CE,
372                                          ExprEngine &Eng,
373                                          ExplodedNode *Pred,
374                                          ExplodedNodeSet &Dst) {
375     return ((const CHECKER *)checker)->inlineCall(CE, Eng, Pred, Dst);
376   }
377
378 public:
379   template <typename CHECKER>
380   static void _register(CHECKER *checker, CheckerManager &mgr) {
381     mgr._registerForInlineCall(
382                  CheckerManager::InlineCallFunc(checker, _inlineCall<CHECKER>));
383   }
384 };
385
386 } // end eval namespace
387
388 class CheckerBase : public ProgramPointTag {
389 public:
390   StringRef getTagDescription() const;
391
392   /// See CheckerManager::runCheckersForPrintState.
393   virtual void printState(raw_ostream &Out, ProgramStateRef State,
394                           const char *NL, const char *Sep) const { }
395 };
396   
397 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
398           typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
399           typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
400           typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
401           typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
402           typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck,
403           typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck,
404           typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck,
405           typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck,
406           typename CHECK19=check::_VoidCheck,typename CHECK20=check::_VoidCheck,
407           typename CHECK21=check::_VoidCheck,typename CHECK22=check::_VoidCheck,
408           typename CHECK23=check::_VoidCheck,typename CHECK24=check::_VoidCheck>
409 class Checker;
410
411 template <>
412 class Checker<check::_VoidCheck>
413   : public CheckerBase 
414 {
415   virtual void anchor();
416 public:
417   static void _register(void *checker, CheckerManager &mgr) { }
418 };
419
420 template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
421           typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
422           typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12,
423           typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16,
424           typename CHECK17,typename CHECK18,typename CHECK19,typename CHECK20,
425           typename CHECK21,typename CHECK22,typename CHECK23,typename CHECK24>
426 class Checker
427     : public CHECK1,
428       public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
429                      CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
430                      CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
431                      CHECK20,CHECK21,CHECK22,CHECK23,CHECK24> {
432 public:
433   template <typename CHECKER>
434   static void _register(CHECKER *checker, CheckerManager &mgr) {
435     CHECK1::_register(checker, mgr);
436     Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
437             CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
438             CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
439             CHECK20,CHECK21,CHECK22,CHECK23,CHECK24>::_register(checker, mgr);
440   }
441 };
442
443 template <typename EVENT>
444 class EventDispatcher {
445   CheckerManager *Mgr;
446 public:
447   EventDispatcher() : Mgr(0) { }
448
449   template <typename CHECKER>
450   static void _register(CHECKER *checker, CheckerManager &mgr) {
451     mgr._registerDispatcherForEvent<EVENT>();
452     static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
453   }
454
455   void dispatchEvent(const EVENT &event) const {
456     Mgr->_dispatchEvent(event);
457   }
458 };
459
460 /// \brief We dereferenced a location that may be null.
461 struct ImplicitNullDerefEvent {
462   SVal Location;
463   bool IsLoad;
464   ExplodedNode *SinkNode;
465   BugReporter *BR;
466 };
467
468 } // end ento namespace
469
470 } // end clang namespace
471
472 #endif