clang  3.7.0
Checker.h
Go to the documentation of this file.
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 
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) {
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) {
59  _checkBody<CHECKER>));
60  }
61 };
62 
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){
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) {
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) {
114  _checkStmt<CHECKER>),
115  _handlesStmt);
116  }
117 };
118 
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) {
130  CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
131  }
132 };
133 
135  template <typename CHECKER>
136  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
137  CheckerContext &C) {
138  ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
139  }
140 
141 public:
142  template <typename CHECKER>
143  static void _register(CHECKER *checker, CheckerManager &mgr) {
145  CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
146  }
147 };
148 
149 class PreCall {
150  template <typename CHECKER>
151  static void _checkCall(void *checker, const CallEvent &msg,
152  CheckerContext &C) {
153  ((const CHECKER *)checker)->checkPreCall(msg, C);
154  }
155 
156 public:
157  template <typename CHECKER>
158  static void _register(CHECKER *checker, CheckerManager &mgr) {
160  CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
161  }
162 };
163 
164 class PostCall {
165  template <typename CHECKER>
166  static void _checkCall(void *checker, const CallEvent &msg,
167  CheckerContext &C) {
168  ((const CHECKER *)checker)->checkPostCall(msg, C);
169  }
170 
171 public:
172  template <typename CHECKER>
173  static void _register(CHECKER *checker, CheckerManager &mgr) {
175  CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
176  }
177 };
178 
179 class Location {
180  template <typename CHECKER>
181  static void _checkLocation(void *checker,
182  const SVal &location, bool isLoad, const Stmt *S,
183  CheckerContext &C) {
184  ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
185  }
186 
187 public:
188  template <typename CHECKER>
189  static void _register(CHECKER *checker, CheckerManager &mgr) {
191  CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
192  }
193 };
194 
195 class Bind {
196  template <typename CHECKER>
197  static void _checkBind(void *checker,
198  const SVal &location, const SVal &val, const Stmt *S,
199  CheckerContext &C) {
200  ((const CHECKER *)checker)->checkBind(location, val, S, C);
201  }
202 
203 public:
204  template <typename CHECKER>
205  static void _register(CHECKER *checker, CheckerManager &mgr) {
206  mgr._registerForBind(
207  CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
208  }
209 };
210 
211 class EndAnalysis {
212  template <typename CHECKER>
213  static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
214  BugReporter &BR, ExprEngine &Eng) {
215  ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
216  }
217 
218 public:
219  template <typename CHECKER>
220  static void _register(CHECKER *checker, CheckerManager &mgr) {
222  CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
223  }
224 };
225 
226 class EndFunction {
227  template <typename CHECKER>
228  static void _checkEndFunction(void *checker,
229  CheckerContext &C) {
230  ((const CHECKER *)checker)->checkEndFunction(C);
231  }
232 
233 public:
234  template <typename CHECKER>
235  static void _register(CHECKER *checker, CheckerManager &mgr) {
237  CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
238  }
239 };
240 
242  template <typename CHECKER>
243  static void _checkBranchCondition(void *checker, const Stmt *Condition,
244  CheckerContext & C) {
245  ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
246  }
247 
248 public:
249  template <typename CHECKER>
250  static void _register(CHECKER *checker, CheckerManager &mgr) {
253  _checkBranchCondition<CHECKER>));
254  }
255 };
256 
257 class LiveSymbols {
258  template <typename CHECKER>
259  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
260  SymbolReaper &SR) {
261  ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
262  }
263 
264 public:
265  template <typename CHECKER>
266  static void _register(CHECKER *checker, CheckerManager &mgr) {
268  CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
269  }
270 };
271 
272 class DeadSymbols {
273  template <typename CHECKER>
274  static void _checkDeadSymbols(void *checker,
275  SymbolReaper &SR, CheckerContext &C) {
276  ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
277  }
278 
279 public:
280  template <typename CHECKER>
281  static void _register(CHECKER *checker, CheckerManager &mgr) {
283  CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
284  }
285 };
286 
288  template <typename CHECKER>
289  static ProgramStateRef
290  _checkRegionChanges(void *checker,
291  ProgramStateRef state,
292  const InvalidatedSymbols *invalidated,
293  ArrayRef<const MemRegion *> Explicits,
295  const CallEvent *Call) {
296  return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
297  Explicits, Regions, Call);
298  }
299  template <typename CHECKER>
300  static bool _wantsRegionChangeUpdate(void *checker,
301  ProgramStateRef state) {
302  return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
303  }
304 
305 public:
306  template <typename CHECKER>
307  static void _register(CHECKER *checker, CheckerManager &mgr) {
310  _checkRegionChanges<CHECKER>),
312  _wantsRegionChangeUpdate<CHECKER>));
313  }
314 };
315 
317  template <typename CHECKER>
318  static ProgramStateRef
319  _checkPointerEscape(void *Checker,
321  const InvalidatedSymbols &Escaped,
322  const CallEvent *Call,
325 
326  if (!ETraits)
327  return ((const CHECKER *)Checker)->checkPointerEscape(State,
328  Escaped,
329  Call,
330  Kind);
331 
332  InvalidatedSymbols RegularEscape;
333  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
334  E = Escaped.end(); I != E; ++I)
335  if (!ETraits->hasTrait(*I,
337  !ETraits->hasTrait(*I,
339  RegularEscape.insert(*I);
340 
341  if (RegularEscape.empty())
342  return State;
343 
344  return ((const CHECKER *)Checker)->checkPointerEscape(State,
345  RegularEscape,
346  Call,
347  Kind);
348  }
349 
350 public:
351  template <typename CHECKER>
352  static void _register(CHECKER *checker, CheckerManager &mgr) {
355  _checkPointerEscape<CHECKER>));
356  }
357 };
358 
360  template <typename CHECKER>
361  static ProgramStateRef
362  _checkConstPointerEscape(void *Checker,
364  const InvalidatedSymbols &Escaped,
365  const CallEvent *Call,
368 
369  if (!ETraits)
370  return State;
371 
372  InvalidatedSymbols ConstEscape;
373  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
374  E = Escaped.end(); I != E; ++I)
375  if (ETraits->hasTrait(*I,
377  !ETraits->hasTrait(*I,
379  ConstEscape.insert(*I);
380 
381  if (ConstEscape.empty())
382  return State;
383 
384  return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
385  ConstEscape,
386  Call,
387  Kind);
388  }
389 
390 public:
391  template <typename CHECKER>
392  static void _register(CHECKER *checker, CheckerManager &mgr) {
395  _checkConstPointerEscape<CHECKER>));
396  }
397 };
398 
399 
400 template <typename EVENT>
401 class Event {
402  template <typename CHECKER>
403  static void _checkEvent(void *checker, const void *event) {
404  ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
405  }
406 public:
407  template <typename CHECKER>
408  static void _register(CHECKER *checker, CheckerManager &mgr) {
409  mgr._registerListenerForEvent<EVENT>(
410  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
411  }
412 };
413 
414 } // end check namespace
415 
416 namespace eval {
417 
418 class Assume {
419  template <typename CHECKER>
420  static ProgramStateRef _evalAssume(void *checker,
421  ProgramStateRef state,
422  const SVal &cond,
423  bool assumption) {
424  return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
425  }
426 
427 public:
428  template <typename CHECKER>
429  static void _register(CHECKER *checker, CheckerManager &mgr) {
431  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
432  }
433 };
434 
435 class Call {
436  template <typename CHECKER>
437  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
438  return ((const CHECKER *)checker)->evalCall(CE, C);
439  }
440 
441 public:
442  template <typename CHECKER>
443  static void _register(CHECKER *checker, CheckerManager &mgr) {
445  CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
446  }
447 };
448 
449 } // end eval namespace
450 
451 class CheckerBase : public ProgramPointTag {
452  CheckName Name;
453  friend class ::clang::ento::CheckerManager;
454 
455 public:
456  StringRef getTagDescription() const override;
457  CheckName getCheckName() const;
458 
459  /// See CheckerManager::runCheckersForPrintState.
460  virtual void printState(raw_ostream &Out, ProgramStateRef State,
461  const char *NL, const char *Sep) const { }
462 };
463 
464 /// Dump checker name to stream.
465 raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
466 
467 /// Tag that can use a checker name as a message provider
468 /// (see SimpleProgramPointTag).
470 public:
471  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
472  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
473 };
474 
475 template <typename CHECK1, typename... CHECKs>
476 class Checker : public CHECK1, public CHECKs..., public CheckerBase {
477 public:
478  template <typename CHECKER>
479  static void _register(CHECKER *checker, CheckerManager &mgr) {
480  CHECK1::_register(checker, mgr);
481  Checker<CHECKs...>::_register(checker, mgr);
482  }
483 };
484 
485 template <typename CHECK1>
486 class Checker<CHECK1> : public CHECK1, public CheckerBase {
487 public:
488  template <typename CHECKER>
489  static void _register(CHECKER *checker, CheckerManager &mgr) {
490  CHECK1::_register(checker, mgr);
491  }
492 };
493 
494 template <typename EVENT>
496  CheckerManager *Mgr;
497 public:
498  EventDispatcher() : Mgr(nullptr) { }
499 
500  template <typename CHECKER>
501  static void _register(CHECKER *checker, CheckerManager &mgr) {
502  mgr._registerDispatcherForEvent<EVENT>();
503  static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
504  }
505 
506  void dispatchEvent(const EVENT &event) const {
507  Mgr->_dispatchEvent(event);
508  }
509 };
510 
511 /// \brief We dereferenced a location that may be null.
514  bool IsLoad;
517 };
518 
519 /// \brief A helper class which wraps a boolean value set to false by default.
520 ///
521 /// This class should behave exactly like 'bool' except that it doesn't need to
522 /// be explicitly initialized.
523 struct DefaultBool {
524  bool val;
526  /*implicit*/ operator bool&() { return val; }
527  /*implicit*/ operator const bool&() const { return val; }
528  DefaultBool &operator=(bool b) { val = b; return *this; }
529 };
530 
531 } // end ento namespace
532 
533 } // end clang namespace
534 
535 #endif
bool hasTrait(SymbolRef Sym, InvalidationKinds IK)
Definition: MemRegion.cpp:1473
void _registerForRegionChanges(CheckRegionChangesFunc checkfn, WantsRegionChangeUpdateFunc wantUpdateFn)
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1320
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:523
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:281
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:266
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:41
void _registerForPreCall(CheckCallFunc checkfn)
LineState State
DefaultBool & operator=(bool b)
Definition: Checker.h:528
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:189
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:112
void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn)
#define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN)
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:791
StringRef getTagDescription() const override
Definition: Checker.cpp:20
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:429
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:408
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:158
We dereferenced a location that may be null.
Definition: Checker.h:512
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:307
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:352
void _registerForBody(CheckDeclFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:173
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:57
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:74
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:501
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForLocation(CheckLocationFunc checkfn)
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
CheckName getCheckName() const
Definition: Checker.cpp:24
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:93
void _registerForPostCall(CheckCallFunc checkfn)
void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn)
#define false
Definition: stdbool.h:33
Kind
void _registerListenerForEvent(CheckEventFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:443
void _registerForBranchCondition(CheckBranchConditionFunc checkfn)
CheckerProgramPointTag(StringRef CheckerName, StringRef Msg)
Definition: Checker.cpp:26
A class responsible for cleaning up unused symbols.
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:220
Tells that a region's contents is not changed.
Definition: MemRegion.h:1334
CheckerFn< void(const void *event)> CheckEventFunc
raw_ostream & operator<<(raw_ostream &Out, const CheckerBase &Checker)
Dump checker name to stream.
Definition: Checker.cpp:34
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:489
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn)
void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn)
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:113
void _registerForEndFunction(CheckEndFunctionFunc checkfn)
void _registerForEvalAssume(EvalAssumeFunc checkfn)
void _registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
void _registerForEvalCall(EvalCallFunc checkfn)
virtual void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const
See CheckerManager::runCheckersForPrintState.
Definition: Checker.h:460
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:250
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:205
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:235
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:506
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:479
TranslationUnitDecl - The top declaration context.
Definition: Decl.h:78
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:392
void _registerForBind(CheckBindFunc checkfn)
void _dispatchEvent(const EVENT &event) const
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:128