clang  8.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, const ReturnStmt *RS,
258  CheckerContext &C) {
259  ((const CHECKER *)checker)->checkEndFunction(RS, 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 
287  template <typename CHECKER>
288  static void _checkNewAllocator(void *checker, const CXXNewExpr *NE,
289  SVal Target, CheckerContext &C) {
290  ((const CHECKER *)checker)->checkNewAllocator(NE, Target, C);
291  }
292 
293 public:
294  template <typename CHECKER>
295  static void _register(CHECKER *checker, CheckerManager &mgr) {
298  _checkNewAllocator<CHECKER>));
299  }
300 };
301 
302 class LiveSymbols {
303  template <typename CHECKER>
304  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
305  SymbolReaper &SR) {
306  ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
307  }
308 
309 public:
310  template <typename CHECKER>
311  static void _register(CHECKER *checker, CheckerManager &mgr) {
313  CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
314  }
315 };
316 
317 class DeadSymbols {
318  template <typename CHECKER>
319  static void _checkDeadSymbols(void *checker,
320  SymbolReaper &SR, CheckerContext &C) {
321  ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
322  }
323 
324 public:
325  template <typename CHECKER>
326  static void _register(CHECKER *checker, CheckerManager &mgr) {
328  CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
329  }
330 };
331 
333  template <typename CHECKER>
334  static ProgramStateRef
335  _checkRegionChanges(void *checker,
337  const InvalidatedSymbols *invalidated,
338  ArrayRef<const MemRegion *> Explicits,
340  const LocationContext *LCtx,
341  const CallEvent *Call) {
342  return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
343  Explicits, Regions,
344  LCtx, Call);
345  }
346 
347 public:
348  template <typename CHECKER>
349  static void _register(CHECKER *checker, CheckerManager &mgr) {
352  _checkRegionChanges<CHECKER>));
353  }
354 };
355 
357  template <typename CHECKER>
358  static ProgramStateRef
359  _checkPointerEscape(void *Checker,
361  const InvalidatedSymbols &Escaped,
362  const CallEvent *Call,
365 
366  if (!ETraits)
367  return ((const CHECKER *)Checker)->checkPointerEscape(State,
368  Escaped,
369  Call,
370  Kind);
371 
372  InvalidatedSymbols RegularEscape;
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  RegularEscape.insert(*I);
380 
381  if (RegularEscape.empty())
382  return State;
383 
384  return ((const CHECKER *)Checker)->checkPointerEscape(State,
385  RegularEscape,
386  Call,
387  Kind);
388  }
389 
390 public:
391  template <typename CHECKER>
392  static void _register(CHECKER *checker, CheckerManager &mgr) {
395  _checkPointerEscape<CHECKER>));
396  }
397 };
398 
400  template <typename CHECKER>
401  static ProgramStateRef
402  _checkConstPointerEscape(void *Checker,
404  const InvalidatedSymbols &Escaped,
405  const CallEvent *Call,
408 
409  if (!ETraits)
410  return State;
411 
412  InvalidatedSymbols ConstEscape;
413  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
414  E = Escaped.end(); I != E; ++I)
415  if (ETraits->hasTrait(*I,
417  !ETraits->hasTrait(*I,
419  ConstEscape.insert(*I);
420 
421  if (ConstEscape.empty())
422  return State;
423 
424  return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
425  ConstEscape,
426  Call,
427  Kind);
428  }
429 
430 public:
431  template <typename CHECKER>
432  static void _register(CHECKER *checker, CheckerManager &mgr) {
435  _checkConstPointerEscape<CHECKER>));
436  }
437 };
438 
439 
440 template <typename EVENT>
441 class Event {
442  template <typename CHECKER>
443  static void _checkEvent(void *checker, const void *event) {
444  ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
445  }
446 public:
447  template <typename CHECKER>
448  static void _register(CHECKER *checker, CheckerManager &mgr) {
449  mgr._registerListenerForEvent<EVENT>(
450  CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
451  }
452 };
453 
454 } // end check namespace
455 
456 namespace eval {
457 
458 class Assume {
459  template <typename CHECKER>
460  static ProgramStateRef _evalAssume(void *checker,
462  const SVal &cond,
463  bool assumption) {
464  return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
465  }
466 
467 public:
468  template <typename CHECKER>
469  static void _register(CHECKER *checker, CheckerManager &mgr) {
471  CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
472  }
473 };
474 
475 class Call {
476  template <typename CHECKER>
477  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
478  return ((const CHECKER *)checker)->evalCall(CE, C);
479  }
480 
481 public:
482  template <typename CHECKER>
483  static void _register(CHECKER *checker, CheckerManager &mgr) {
485  CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
486  }
487 };
488 
489 } // end eval namespace
490 
491 class CheckerBase : public ProgramPointTag {
492  CheckName Name;
493  friend class ::clang::ento::CheckerManager;
494 
495 public:
496  StringRef getTagDescription() const override;
497  CheckName getCheckName() const;
498 
499  /// See CheckerManager::runCheckersForPrintState.
500  virtual void printState(raw_ostream &Out, ProgramStateRef State,
501  const char *NL, const char *Sep) const { }
502 };
503 
504 /// Dump checker name to stream.
505 raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
506 
507 /// Tag that can use a checker name as a message provider
508 /// (see SimpleProgramPointTag).
510 public:
511  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
512  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
513 };
514 
515 template <typename CHECK1, typename... CHECKs>
516 class Checker : public CHECK1, public CHECKs..., public CheckerBase {
517 public:
518  template <typename CHECKER>
519  static void _register(CHECKER *checker, CheckerManager &mgr) {
520  CHECK1::_register(checker, mgr);
521  Checker<CHECKs...>::_register(checker, mgr);
522  }
523 };
524 
525 template <typename CHECK1>
526 class Checker<CHECK1> : public CHECK1, public CheckerBase {
527 public:
528  template <typename CHECKER>
529  static void _register(CHECKER *checker, CheckerManager &mgr) {
530  CHECK1::_register(checker, mgr);
531  }
532 };
533 
534 template <typename EVENT>
536  CheckerManager *Mgr;
537 public:
538  EventDispatcher() : Mgr(nullptr) { }
539 
540  template <typename CHECKER>
541  static void _register(CHECKER *checker, CheckerManager &mgr) {
542  mgr._registerDispatcherForEvent<EVENT>();
543  static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
544  }
545 
546  void dispatchEvent(const EVENT &event) const {
547  Mgr->_dispatchEvent(event);
548  }
549 };
550 
551 /// We dereferenced a location that may be null.
554  bool IsLoad;
557  // When true, the dereference is in the source code directly. When false, the
558  // dereference might happen later (for example pointer passed to a parameter
559  // that is marked with nonnull attribute.)
561 };
562 
563 /// A helper class which wraps a boolean value set to false by default.
564 ///
565 /// This class should behave exactly like 'bool' except that it doesn't need to
566 /// be explicitly initialized.
567 struct DefaultBool {
568  bool val;
569  DefaultBool() : val(false) {}
570  /*implicit*/ operator bool&() { return val; }
571  /*implicit*/ operator const bool&() const { return val; }
572  DefaultBool &operator=(bool b) { val = b; return *this; }
573 };
574 
575 } // end ento namespace
576 
577 } // end clang namespace
578 
579 #endif
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1588
void _dispatchEvent(const EVENT &event) const
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
Stmt - This represents one statement.
Definition: Stmt.h:66
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1438
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:567
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:295
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:326
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:311
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:572
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:966
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:469
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:448
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:173
We dereferenced a location that may be null.
Definition: Checker.h:552
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:349
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:392
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:541
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForLocation(CheckLocationFunc checkfn)
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1444
CheckerFn< void(const void *event)> CheckEventFunc
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:412
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:483
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Definition: ExprCXX.h:1873
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:76
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:1453
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:529
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:182
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 _registerForNewAllocator(CheckNewAllocatorFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:249
void _registerForBeginFunction(CheckBeginFunctionFunc checkfn)
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:2285
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:519
The top declaration context.
Definition: Decl.h:107
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:546
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:432
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:509
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:500
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:128