]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h
Update clang to release_39 branch r276489, and resolve conflicts.
[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_STATICANALYZER_CORE_CHECKER_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
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 template <typename DECL>
29 class ASTDecl {
30   template <typename CHECKER>
31   static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
32                          BugReporter &BR) {
33     ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
34   }
35
36   static bool _handlesDecl(const Decl *D) {
37     return isa<DECL>(D);
38   }
39 public:
40   template <typename CHECKER>
41   static void _register(CHECKER *checker, CheckerManager &mgr) {
42     mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
43                                                        _checkDecl<CHECKER>),
44                          _handlesDecl);
45   }
46 };
47
48 class ASTCodeBody {
49   template <typename CHECKER>
50   static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
51                          BugReporter &BR) {
52     ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
53   }
54
55 public:
56   template <typename CHECKER>
57   static void _register(CHECKER *checker, CheckerManager &mgr) {
58     mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
59                                                        _checkBody<CHECKER>));
60   }
61 };
62
63 class EndOfTranslationUnit {
64   template <typename CHECKER>
65   static void _checkEndOfTranslationUnit(void *checker,
66                                          const TranslationUnitDecl *TU, 
67                                          AnalysisManager& mgr,
68                                          BugReporter &BR) {
69     ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
70   }
71
72 public:
73   template <typename CHECKER>
74   static void _register(CHECKER *checker, CheckerManager &mgr){
75     mgr._registerForEndOfTranslationUnit(
76                               CheckerManager::CheckEndOfTranslationUnit(checker,
77                                           _checkEndOfTranslationUnit<CHECKER>));
78   }
79 };
80
81 template <typename STMT>
82 class PreStmt {
83   template <typename CHECKER>
84   static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
85     ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
86   }
87
88   static bool _handlesStmt(const Stmt *S) {
89     return isa<STMT>(S);
90   }
91 public:
92   template <typename CHECKER>
93   static void _register(CHECKER *checker, CheckerManager &mgr) {
94     mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
95                                                           _checkStmt<CHECKER>),
96                             _handlesStmt);
97   }
98 };
99
100 template <typename STMT>
101 class PostStmt {
102   template <typename CHECKER>
103   static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
104     ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
105   }
106
107   static bool _handlesStmt(const Stmt *S) {
108     return isa<STMT>(S);
109   }
110 public:
111   template <typename CHECKER>
112   static void _register(CHECKER *checker, CheckerManager &mgr) {
113     mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
114                                                            _checkStmt<CHECKER>),
115                              _handlesStmt);
116   }
117 };
118
119 class PreObjCMessage {
120   template <typename CHECKER>
121   static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
122                                 CheckerContext &C) {
123     ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
124   }
125
126 public:
127   template <typename CHECKER>
128   static void _register(CHECKER *checker, CheckerManager &mgr) {
129     mgr._registerForPreObjCMessage(
130      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
131   }
132 };
133
134 class ObjCMessageNil {
135   template <typename CHECKER>
136   static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
137                                 CheckerContext &C) {
138     ((const CHECKER *)checker)->checkObjCMessageNil(msg, C);
139   }
140
141 public:
142   template <typename CHECKER>
143   static void _register(CHECKER *checker, CheckerManager &mgr) {
144     mgr._registerForObjCMessageNil(
145      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
146   }
147 };
148
149 class PostObjCMessage {
150   template <typename CHECKER>
151   static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
152                                 CheckerContext &C) {
153     ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
154   }
155
156 public:
157   template <typename CHECKER>
158   static void _register(CHECKER *checker, CheckerManager &mgr) {
159     mgr._registerForPostObjCMessage(
160      CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
161   }
162 };
163
164 class PreCall {
165   template <typename CHECKER>
166   static void _checkCall(void *checker, const CallEvent &msg,
167                          CheckerContext &C) {
168     ((const CHECKER *)checker)->checkPreCall(msg, C);
169   }
170
171 public:
172   template <typename CHECKER>
173   static void _register(CHECKER *checker, CheckerManager &mgr) {
174     mgr._registerForPreCall(
175      CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
176   }
177 };
178
179 class PostCall {
180   template <typename CHECKER>
181   static void _checkCall(void *checker, const CallEvent &msg,
182                          CheckerContext &C) {
183     ((const CHECKER *)checker)->checkPostCall(msg, C);
184   }
185
186 public:
187   template <typename CHECKER>
188   static void _register(CHECKER *checker, CheckerManager &mgr) {
189     mgr._registerForPostCall(
190      CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
191   }
192 };
193
194 class Location {
195   template <typename CHECKER>
196   static void _checkLocation(void *checker,
197                              const SVal &location, bool isLoad, const Stmt *S,
198                              CheckerContext &C) {
199     ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
200   }
201
202 public:
203   template <typename CHECKER>
204   static void _register(CHECKER *checker, CheckerManager &mgr) {
205     mgr._registerForLocation(
206            CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
207   }
208 };
209
210 class Bind {
211   template <typename CHECKER>
212   static void _checkBind(void *checker,
213                          const SVal &location, const SVal &val, const Stmt *S,
214                          CheckerContext &C) {
215     ((const CHECKER *)checker)->checkBind(location, val, S, C);
216   }
217
218 public:
219   template <typename CHECKER>
220   static void _register(CHECKER *checker, CheckerManager &mgr) {
221     mgr._registerForBind(
222            CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
223   }
224 };
225
226 class EndAnalysis {
227   template <typename CHECKER>
228   static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
229                                 BugReporter &BR, ExprEngine &Eng) {
230     ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
231   }
232
233 public:
234   template <typename CHECKER>
235   static void _register(CHECKER *checker, CheckerManager &mgr) {
236     mgr._registerForEndAnalysis(
237      CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
238   }
239 };
240
241 class BeginFunction {
242   template <typename CHECKER>
243   static void _checkBeginFunction(void *checker, CheckerContext &C) {
244     ((const CHECKER *)checker)->checkBeginFunction(C);
245   }
246
247 public:
248   template <typename CHECKER>
249   static void _register(CHECKER *checker, CheckerManager &mgr) {
250     mgr._registerForBeginFunction(CheckerManager::CheckBeginFunctionFunc(
251         checker, _checkBeginFunction<CHECKER>));
252   }
253 };
254
255 class EndFunction {
256   template <typename CHECKER>
257   static void _checkEndFunction(void *checker,
258                                 CheckerContext &C) {
259     ((const CHECKER *)checker)->checkEndFunction(C);
260   }
261
262 public:
263   template <typename CHECKER>
264   static void _register(CHECKER *checker, CheckerManager &mgr) {
265     mgr._registerForEndFunction(
266      CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
267   }
268 };
269
270 class BranchCondition {
271   template <typename CHECKER>
272   static void _checkBranchCondition(void *checker, const Stmt *Condition,
273                                     CheckerContext & C) {
274     ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
275   }
276
277 public:
278   template <typename CHECKER>
279   static void _register(CHECKER *checker, CheckerManager &mgr) {
280     mgr._registerForBranchCondition(
281       CheckerManager::CheckBranchConditionFunc(checker,
282                                                _checkBranchCondition<CHECKER>));
283   }
284 };
285
286 class LiveSymbols {
287   template <typename CHECKER>
288   static void _checkLiveSymbols(void *checker, ProgramStateRef state,
289                                 SymbolReaper &SR) {
290     ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
291   }
292
293 public:
294   template <typename CHECKER>
295   static void _register(CHECKER *checker, CheckerManager &mgr) {
296     mgr._registerForLiveSymbols(
297      CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
298   }
299 };
300
301 class DeadSymbols {
302   template <typename CHECKER>
303   static void _checkDeadSymbols(void *checker,
304                                 SymbolReaper &SR, CheckerContext &C) {
305     ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
306   }
307
308 public:
309   template <typename CHECKER>
310   static void _register(CHECKER *checker, CheckerManager &mgr) {
311     mgr._registerForDeadSymbols(
312      CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
313   }
314 };
315
316 class RegionChanges {
317   template <typename CHECKER>
318   static ProgramStateRef 
319   _checkRegionChanges(void *checker,
320                       ProgramStateRef state,
321                       const InvalidatedSymbols *invalidated,
322                       ArrayRef<const MemRegion *> Explicits,
323                       ArrayRef<const MemRegion *> Regions,
324                       const CallEvent *Call) {
325     return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
326                                                       Explicits, Regions, Call);
327   }
328   template <typename CHECKER>
329   static bool _wantsRegionChangeUpdate(void *checker,
330                                        ProgramStateRef state) {
331     return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
332   }
333
334 public:
335   template <typename CHECKER>
336   static void _register(CHECKER *checker, CheckerManager &mgr) {
337     mgr._registerForRegionChanges(
338           CheckerManager::CheckRegionChangesFunc(checker,
339                                                  _checkRegionChanges<CHECKER>),
340           CheckerManager::WantsRegionChangeUpdateFunc(checker,
341                                             _wantsRegionChangeUpdate<CHECKER>));
342   }
343 };
344
345 class PointerEscape {
346   template <typename CHECKER>
347   static ProgramStateRef
348   _checkPointerEscape(void *Checker,
349                      ProgramStateRef State,
350                      const InvalidatedSymbols &Escaped,
351                      const CallEvent *Call,
352                      PointerEscapeKind Kind,
353                      RegionAndSymbolInvalidationTraits *ETraits) {
354
355     if (!ETraits)
356       return ((const CHECKER *)Checker)->checkPointerEscape(State,
357                                                             Escaped,
358                                                             Call,
359                                                             Kind);
360
361     InvalidatedSymbols RegularEscape;
362     for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 
363                                             E = Escaped.end(); I != E; ++I)
364       if (!ETraits->hasTrait(*I,
365               RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
366           !ETraits->hasTrait(*I,
367               RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
368         RegularEscape.insert(*I);
369
370     if (RegularEscape.empty())
371       return State;
372
373     return ((const CHECKER *)Checker)->checkPointerEscape(State,
374                                                           RegularEscape,
375                                                           Call,
376                                                           Kind);
377   }
378
379 public:
380   template <typename CHECKER>
381   static void _register(CHECKER *checker, CheckerManager &mgr) {
382     mgr._registerForPointerEscape(
383           CheckerManager::CheckPointerEscapeFunc(checker,
384                                                 _checkPointerEscape<CHECKER>));
385   }
386 };
387
388 class ConstPointerEscape {
389   template <typename CHECKER>
390   static ProgramStateRef
391   _checkConstPointerEscape(void *Checker,
392                       ProgramStateRef State,
393                       const InvalidatedSymbols &Escaped,
394                       const CallEvent *Call,
395                       PointerEscapeKind Kind,
396                       RegionAndSymbolInvalidationTraits *ETraits) {
397
398     if (!ETraits)
399       return State;
400
401     InvalidatedSymbols ConstEscape;
402     for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 
403                                             E = Escaped.end(); I != E; ++I)
404       if (ETraits->hasTrait(*I,
405               RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
406           !ETraits->hasTrait(*I,
407               RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
408         ConstEscape.insert(*I);
409
410     if (ConstEscape.empty())
411       return State;
412
413     return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
414                                                                ConstEscape,
415                                                                Call,
416                                                                Kind);
417   }
418
419 public:
420   template <typename CHECKER>
421   static void _register(CHECKER *checker, CheckerManager &mgr) {
422     mgr._registerForPointerEscape(
423       CheckerManager::CheckPointerEscapeFunc(checker,
424                                             _checkConstPointerEscape<CHECKER>));
425   }
426 };
427
428   
429 template <typename EVENT>
430 class Event {
431   template <typename CHECKER>
432   static void _checkEvent(void *checker, const void *event) {
433     ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
434   }
435 public:
436   template <typename CHECKER>
437   static void _register(CHECKER *checker, CheckerManager &mgr) {
438     mgr._registerListenerForEvent<EVENT>(
439                  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
440   }
441 };
442
443 } // end check namespace
444
445 namespace eval {
446
447 class Assume {
448   template <typename CHECKER>
449   static ProgramStateRef _evalAssume(void *checker,
450                                          ProgramStateRef state,
451                                          const SVal &cond,
452                                          bool assumption) {
453     return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
454   }
455
456 public:
457   template <typename CHECKER>
458   static void _register(CHECKER *checker, CheckerManager &mgr) {
459     mgr._registerForEvalAssume(
460                  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
461   }
462 };
463
464 class Call {
465   template <typename CHECKER>
466   static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
467     return ((const CHECKER *)checker)->evalCall(CE, C);
468   }
469
470 public:
471   template <typename CHECKER>
472   static void _register(CHECKER *checker, CheckerManager &mgr) {
473     mgr._registerForEvalCall(
474                      CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
475   }
476 };
477
478 } // end eval namespace
479
480 class CheckerBase : public ProgramPointTag {
481   CheckName Name;
482   friend class ::clang::ento::CheckerManager;
483
484 public:
485   StringRef getTagDescription() const override;
486   CheckName getCheckName() const;
487
488   /// See CheckerManager::runCheckersForPrintState.
489   virtual void printState(raw_ostream &Out, ProgramStateRef State,
490                           const char *NL, const char *Sep) const { }
491 };
492
493 /// Dump checker name to stream.
494 raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
495
496 /// Tag that can use a checker name as a message provider 
497 /// (see SimpleProgramPointTag).
498 class CheckerProgramPointTag : public SimpleProgramPointTag {
499 public:
500   CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
501   CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
502 };
503
504 template <typename CHECK1, typename... CHECKs>
505 class Checker : public CHECK1, public CHECKs..., public CheckerBase {
506 public:
507   template <typename CHECKER>
508   static void _register(CHECKER *checker, CheckerManager &mgr) {
509     CHECK1::_register(checker, mgr);
510     Checker<CHECKs...>::_register(checker, mgr);
511   }
512 };
513
514 template <typename CHECK1>
515 class Checker<CHECK1> : public CHECK1, public CheckerBase {
516 public:
517   template <typename CHECKER>
518   static void _register(CHECKER *checker, CheckerManager &mgr) {
519     CHECK1::_register(checker, mgr);
520   }
521 };
522
523 template <typename EVENT>
524 class EventDispatcher {
525   CheckerManager *Mgr;
526 public:
527   EventDispatcher() : Mgr(nullptr) { }
528
529   template <typename CHECKER>
530   static void _register(CHECKER *checker, CheckerManager &mgr) {
531     mgr._registerDispatcherForEvent<EVENT>();
532     static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
533   }
534
535   void dispatchEvent(const EVENT &event) const {
536     Mgr->_dispatchEvent(event);
537   }
538 };
539
540 /// \brief We dereferenced a location that may be null.
541 struct ImplicitNullDerefEvent {
542   SVal Location;
543   bool IsLoad;
544   ExplodedNode *SinkNode;
545   BugReporter *BR;
546   // When true, the dereference is in the source code directly. When false, the
547   // dereference might happen later (for example pointer passed to a parameter
548   // that is marked with nonnull attribute.)
549   bool IsDirectDereference;
550 };
551
552 /// \brief A helper class which wraps a boolean value set to false by default.
553 ///
554 /// This class should behave exactly like 'bool' except that it doesn't need to
555 /// be explicitly initialized.
556 struct DefaultBool {
557   bool val;
558   DefaultBool() : val(false) {}
559   /*implicit*/ operator bool&() { return val; }
560   /*implicit*/ operator const bool&() const { return val; }
561   DefaultBool &operator=(bool b) { val = b; return *this; }
562 };
563
564 } // end ento namespace
565
566 } // end clang namespace
567
568 #endif