clang  3.8.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)->checkObjCMessageNil(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 
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) {
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) {
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) {
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) {
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) {
237  CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
238  }
239 };
240 
241 class EndFunction {
242  template <typename CHECKER>
243  static void _checkEndFunction(void *checker,
244  CheckerContext &C) {
245  ((const CHECKER *)checker)->checkEndFunction(C);
246  }
247 
248 public:
249  template <typename CHECKER>
250  static void _register(CHECKER *checker, CheckerManager &mgr) {
252  CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
253  }
254 };
255 
257  template <typename CHECKER>
258  static void _checkBranchCondition(void *checker, const Stmt *Condition,
259  CheckerContext & C) {
260  ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
261  }
262 
263 public:
264  template <typename CHECKER>
265  static void _register(CHECKER *checker, CheckerManager &mgr) {
268  _checkBranchCondition<CHECKER>));
269  }
270 };
271 
272 class LiveSymbols {
273  template <typename CHECKER>
274  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
275  SymbolReaper &SR) {
276  ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
277  }
278 
279 public:
280  template <typename CHECKER>
281  static void _register(CHECKER *checker, CheckerManager &mgr) {
283  CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
284  }
285 };
286 
287 class DeadSymbols {
288  template <typename CHECKER>
289  static void _checkDeadSymbols(void *checker,
290  SymbolReaper &SR, CheckerContext &C) {
291  ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
292  }
293 
294 public:
295  template <typename CHECKER>
296  static void _register(CHECKER *checker, CheckerManager &mgr) {
298  CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
299  }
300 };
301 
303  template <typename CHECKER>
304  static ProgramStateRef
305  _checkRegionChanges(void *checker,
306  ProgramStateRef state,
307  const InvalidatedSymbols *invalidated,
308  ArrayRef<const MemRegion *> Explicits,
310  const CallEvent *Call) {
311  return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
312  Explicits, Regions, Call);
313  }
314  template <typename CHECKER>
315  static bool _wantsRegionChangeUpdate(void *checker,
316  ProgramStateRef state) {
317  return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
318  }
319 
320 public:
321  template <typename CHECKER>
322  static void _register(CHECKER *checker, CheckerManager &mgr) {
325  _checkRegionChanges<CHECKER>),
327  _wantsRegionChangeUpdate<CHECKER>));
328  }
329 };
330 
332  template <typename CHECKER>
333  static ProgramStateRef
334  _checkPointerEscape(void *Checker,
336  const InvalidatedSymbols &Escaped,
337  const CallEvent *Call,
340 
341  if (!ETraits)
342  return ((const CHECKER *)Checker)->checkPointerEscape(State,
343  Escaped,
344  Call,
345  Kind);
346 
347  InvalidatedSymbols RegularEscape;
348  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
349  E = Escaped.end(); I != E; ++I)
350  if (!ETraits->hasTrait(*I,
352  !ETraits->hasTrait(*I,
354  RegularEscape.insert(*I);
355 
356  if (RegularEscape.empty())
357  return State;
358 
359  return ((const CHECKER *)Checker)->checkPointerEscape(State,
360  RegularEscape,
361  Call,
362  Kind);
363  }
364 
365 public:
366  template <typename CHECKER>
367  static void _register(CHECKER *checker, CheckerManager &mgr) {
370  _checkPointerEscape<CHECKER>));
371  }
372 };
373 
375  template <typename CHECKER>
376  static ProgramStateRef
377  _checkConstPointerEscape(void *Checker,
379  const InvalidatedSymbols &Escaped,
380  const CallEvent *Call,
383 
384  if (!ETraits)
385  return State;
386 
387  InvalidatedSymbols ConstEscape;
388  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
389  E = Escaped.end(); I != E; ++I)
390  if (ETraits->hasTrait(*I,
392  !ETraits->hasTrait(*I,
394  ConstEscape.insert(*I);
395 
396  if (ConstEscape.empty())
397  return State;
398 
399  return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
400  ConstEscape,
401  Call,
402  Kind);
403  }
404 
405 public:
406  template <typename CHECKER>
407  static void _register(CHECKER *checker, CheckerManager &mgr) {
410  _checkConstPointerEscape<CHECKER>));
411  }
412 };
413 
414 
415 template <typename EVENT>
416 class Event {
417  template <typename CHECKER>
418  static void _checkEvent(void *checker, const void *event) {
419  ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
420  }
421 public:
422  template <typename CHECKER>
423  static void _register(CHECKER *checker, CheckerManager &mgr) {
424  mgr._registerListenerForEvent<EVENT>(
425  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
426  }
427 };
428 
429 } // end check namespace
430 
431 namespace eval {
432 
433 class Assume {
434  template <typename CHECKER>
435  static ProgramStateRef _evalAssume(void *checker,
436  ProgramStateRef state,
437  const SVal &cond,
438  bool assumption) {
439  return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
440  }
441 
442 public:
443  template <typename CHECKER>
444  static void _register(CHECKER *checker, CheckerManager &mgr) {
446  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
447  }
448 };
449 
450 class Call {
451  template <typename CHECKER>
452  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
453  return ((const CHECKER *)checker)->evalCall(CE, C);
454  }
455 
456 public:
457  template <typename CHECKER>
458  static void _register(CHECKER *checker, CheckerManager &mgr) {
460  CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
461  }
462 };
463 
464 } // end eval namespace
465 
466 class CheckerBase : public ProgramPointTag {
467  CheckName Name;
468  friend class ::clang::ento::CheckerManager;
469 
470 public:
471  StringRef getTagDescription() const override;
472  CheckName getCheckName() const;
473 
474  /// See CheckerManager::runCheckersForPrintState.
475  virtual void printState(raw_ostream &Out, ProgramStateRef State,
476  const char *NL, const char *Sep) const { }
477 };
478 
479 /// Dump checker name to stream.
480 raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
481 
482 /// Tag that can use a checker name as a message provider
483 /// (see SimpleProgramPointTag).
485 public:
486  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
487  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
488 };
489 
490 template <typename CHECK1, typename... CHECKs>
491 class Checker : public CHECK1, public CHECKs..., public CheckerBase {
492 public:
493  template <typename CHECKER>
494  static void _register(CHECKER *checker, CheckerManager &mgr) {
495  CHECK1::_register(checker, mgr);
496  Checker<CHECKs...>::_register(checker, mgr);
497  }
498 };
499 
500 template <typename CHECK1>
501 class Checker<CHECK1> : public CHECK1, public CheckerBase {
502 public:
503  template <typename CHECKER>
504  static void _register(CHECKER *checker, CheckerManager &mgr) {
505  CHECK1::_register(checker, mgr);
506  }
507 };
508 
509 template <typename EVENT>
511  CheckerManager *Mgr;
512 public:
513  EventDispatcher() : Mgr(nullptr) { }
514 
515  template <typename CHECKER>
516  static void _register(CHECKER *checker, CheckerManager &mgr) {
517  mgr._registerDispatcherForEvent<EVENT>();
518  static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
519  }
520 
521  void dispatchEvent(const EVENT &event) const {
522  Mgr->_dispatchEvent(event);
523  }
524 };
525 
526 /// \brief We dereferenced a location that may be null.
529  bool IsLoad;
532  // When true, the dereference is in the source code directly. When false, the
533  // dereference might happen later (for example pointer passed to a parameter
534  // that is marked with nonnull attribute.)
536 };
537 
538 /// \brief A helper class which wraps a boolean value set to false by default.
539 ///
540 /// This class should behave exactly like 'bool' except that it doesn't need to
541 /// be explicitly initialized.
542 struct DefaultBool {
543  bool val;
545  /*implicit*/ operator bool&() { return val; }
546  /*implicit*/ operator const bool&() const { return val; }
547  DefaultBool &operator=(bool b) { val = b; return *this; }
548 };
549 
550 } // end ento namespace
551 
552 } // end clang namespace
553 
554 #endif
bool hasTrait(SymbolRef Sym, InvalidationKinds IK)
Definition: MemRegion.cpp:1490
void _registerForRegionChanges(CheckRegionChangesFunc checkfn, WantsRegionChangeUpdateFunc wantUpdateFn)
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1332
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:542
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:77
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:296
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:281
void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:41
void _registerForPreCall(CheckCallFunc checkfn)
LineState State
DefaultBool & operator=(bool b)
Definition: Checker.h:547
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:204
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:849
StringRef getTagDescription() const override
Definition: Checker.cpp:20
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:444
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:423
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:173
detail::InMemoryDirectory::const_iterator I
We dereferenced a location that may be null.
Definition: Checker.h:527
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:322
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:367
void _registerForBody(CheckDeclFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:188
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:516
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)
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:388
void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn)
#define false
Definition: stdbool.h:33
Kind
void _registerListenerForEvent(CheckEventFunc checkfn)
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:40
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:458
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:44
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:235
Tells that a region's contents is not changed.
Definition: MemRegion.h:1346
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:504
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:158
detail::InMemoryDirectory::const_iterator E
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:475
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:265
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:220
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:250
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2134
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:521
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:494
TranslationUnitDecl - The top declaration context.
Definition: Decl.h:79
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:407
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:484
void _registerForBind(CheckBindFunc checkfn)
void _dispatchEvent(const EVENT &event) const
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:128