clang  6.0.0svn
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 
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) {
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) {
266  CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
267  }
268 };
269 
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) {
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) {
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) {
312  CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
313  }
314 };
315 
317  template <typename CHECKER>
318  static ProgramStateRef
319  _checkRegionChanges(void *checker,
321  const InvalidatedSymbols *invalidated,
322  ArrayRef<const MemRegion *> Explicits,
324  const LocationContext *LCtx,
325  const CallEvent *Call) {
326  return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
327  Explicits, Regions,
328  LCtx, Call);
329  }
330 
331 public:
332  template <typename CHECKER>
333  static void _register(CHECKER *checker, CheckerManager &mgr) {
336  _checkRegionChanges<CHECKER>));
337  }
338 };
339 
341  template <typename CHECKER>
342  static ProgramStateRef
343  _checkPointerEscape(void *Checker,
345  const InvalidatedSymbols &Escaped,
346  const CallEvent *Call,
349 
350  if (!ETraits)
351  return ((const CHECKER *)Checker)->checkPointerEscape(State,
352  Escaped,
353  Call,
354  Kind);
355 
356  InvalidatedSymbols RegularEscape;
357  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
358  E = Escaped.end(); I != E; ++I)
359  if (!ETraits->hasTrait(*I,
361  !ETraits->hasTrait(*I,
363  RegularEscape.insert(*I);
364 
365  if (RegularEscape.empty())
366  return State;
367 
368  return ((const CHECKER *)Checker)->checkPointerEscape(State,
369  RegularEscape,
370  Call,
371  Kind);
372  }
373 
374 public:
375  template <typename CHECKER>
376  static void _register(CHECKER *checker, CheckerManager &mgr) {
379  _checkPointerEscape<CHECKER>));
380  }
381 };
382 
384  template <typename CHECKER>
385  static ProgramStateRef
386  _checkConstPointerEscape(void *Checker,
388  const InvalidatedSymbols &Escaped,
389  const CallEvent *Call,
392 
393  if (!ETraits)
394  return State;
395 
396  InvalidatedSymbols ConstEscape;
397  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
398  E = Escaped.end(); I != E; ++I)
399  if (ETraits->hasTrait(*I,
401  !ETraits->hasTrait(*I,
403  ConstEscape.insert(*I);
404 
405  if (ConstEscape.empty())
406  return State;
407 
408  return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
409  ConstEscape,
410  Call,
411  Kind);
412  }
413 
414 public:
415  template <typename CHECKER>
416  static void _register(CHECKER *checker, CheckerManager &mgr) {
419  _checkConstPointerEscape<CHECKER>));
420  }
421 };
422 
423 
424 template <typename EVENT>
425 class Event {
426  template <typename CHECKER>
427  static void _checkEvent(void *checker, const void *event) {
428  ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
429  }
430 public:
431  template <typename CHECKER>
432  static void _register(CHECKER *checker, CheckerManager &mgr) {
433  mgr._registerListenerForEvent<EVENT>(
434  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
435  }
436 };
437 
438 } // end check namespace
439 
440 namespace eval {
441 
442 class Assume {
443  template <typename CHECKER>
444  static ProgramStateRef _evalAssume(void *checker,
446  const SVal &cond,
447  bool assumption) {
448  return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
449  }
450 
451 public:
452  template <typename CHECKER>
453  static void _register(CHECKER *checker, CheckerManager &mgr) {
455  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
456  }
457 };
458 
459 class Call {
460  template <typename CHECKER>
461  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
462  return ((const CHECKER *)checker)->evalCall(CE, C);
463  }
464 
465 public:
466  template <typename CHECKER>
467  static void _register(CHECKER *checker, CheckerManager &mgr) {
469  CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
470  }
471 };
472 
473 } // end eval namespace
474 
475 class CheckerBase : public ProgramPointTag {
476  CheckName Name;
477  friend class ::clang::ento::CheckerManager;
478 
479 public:
480  StringRef getTagDescription() const override;
481  CheckName getCheckName() const;
482 
483  /// See CheckerManager::runCheckersForPrintState.
484  virtual void printState(raw_ostream &Out, ProgramStateRef State,
485  const char *NL, const char *Sep) const { }
486 };
487 
488 /// Dump checker name to stream.
489 raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
490 
491 /// Tag that can use a checker name as a message provider
492 /// (see SimpleProgramPointTag).
494 public:
495  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
496  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
497 };
498 
499 template <typename CHECK1, typename... CHECKs>
500 class Checker : public CHECK1, public CHECKs..., public CheckerBase {
501 public:
502  template <typename CHECKER>
503  static void _register(CHECKER *checker, CheckerManager &mgr) {
504  CHECK1::_register(checker, mgr);
505  Checker<CHECKs...>::_register(checker, mgr);
506  }
507 };
508 
509 template <typename CHECK1>
510 class Checker<CHECK1> : public CHECK1, public CheckerBase {
511 public:
512  template <typename CHECKER>
513  static void _register(CHECKER *checker, CheckerManager &mgr) {
514  CHECK1::_register(checker, mgr);
515  }
516 };
517 
518 template <typename EVENT>
520  CheckerManager *Mgr;
521 public:
522  EventDispatcher() : Mgr(nullptr) { }
523 
524  template <typename CHECKER>
525  static void _register(CHECKER *checker, CheckerManager &mgr) {
526  mgr._registerDispatcherForEvent<EVENT>();
527  static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
528  }
529 
530  void dispatchEvent(const EVENT &event) const {
531  Mgr->_dispatchEvent(event);
532  }
533 };
534 
535 /// \brief We dereferenced a location that may be null.
538  bool IsLoad;
541  // When true, the dereference is in the source code directly. When false, the
542  // dereference might happen later (for example pointer passed to a parameter
543  // that is marked with nonnull attribute.)
545 };
546 
547 /// \brief A helper class which wraps a boolean value set to false by default.
548 ///
549 /// This class should behave exactly like 'bool' except that it doesn't need to
550 /// be explicitly initialized.
551 struct DefaultBool {
552  bool val;
553  DefaultBool() : val(false) {}
554  /*implicit*/ operator bool&() { return val; }
555  /*implicit*/ operator const bool&() const { return val; }
556  DefaultBool &operator=(bool b) { val = b; return *this; }
557 };
558 
559 } // end ento namespace
560 
561 } // end clang namespace
562 
563 #endif
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1502
void _dispatchEvent(const EVENT &event) const
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
Stmt - This represents one statement.
Definition: Stmt.h:60
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1383
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:551
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:81
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:310
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:295
void _registerForBeginFunction(CheckEndFunctionFunc checkfn)
void _registerForRegionChanges(CheckRegionChangesFunc checkfn)
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:556
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:204
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
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:870
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:453
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:432
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:173
We dereferenced a location that may be null.
Definition: Checker.h:536
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:333
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:376
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:525
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForLocation(CheckLocationFunc checkfn)
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
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:403
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:467
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
void _registerForBranchCondition(CheckBranchConditionFunc checkfn)
A class responsible for cleaning up unused symbols.
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:235
Tells that a region&#39;s contents is not changed.
Definition: MemRegion.h:1397
CheckerFn< void(const void *event)> CheckEventFunc
Dataflow Directional Tag Classes.
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:513
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:158
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:140
void _registerForEndFunction(CheckEndFunctionFunc checkfn)
void _registerForEvalAssume(EvalAssumeFunc checkfn)
void _registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:249
void _registerForEvalCall(EvalCallFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:279
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:220
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:264
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2209
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:503
TranslationUnitDecl - The top declaration context.
Definition: Decl.h:80
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:530
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:416
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:493
void _registerForBind(CheckBindFunc checkfn)
virtual void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const
See CheckerManager::runCheckersForPrintState.
Definition: Checker.h:484
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:128