clang  3.9.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 
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 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) {
339  _checkRegionChanges<CHECKER>),
341  _wantsRegionChangeUpdate<CHECKER>));
342  }
343 };
344 
346  template <typename CHECKER>
347  static ProgramStateRef
348  _checkPointerEscape(void *Checker,
350  const InvalidatedSymbols &Escaped,
351  const CallEvent *Call,
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,
366  !ETraits->hasTrait(*I,
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) {
384  _checkPointerEscape<CHECKER>));
385  }
386 };
387 
389  template <typename CHECKER>
390  static ProgramStateRef
391  _checkConstPointerEscape(void *Checker,
393  const InvalidatedSymbols &Escaped,
394  const CallEvent *Call,
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,
406  !ETraits->hasTrait(*I,
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) {
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,
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) {
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) {
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).
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>
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.
543  bool IsLoad;
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.)
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;
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
void _registerForRegionChanges(CheckRegionChangesFunc checkfn, WantsRegionChangeUpdateFunc wantUpdateFn)
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1316
A helper class which wraps a boolean value set to false by default.
Definition: Checker.h:556
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 _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:561
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:881
StringRef getTagDescription() const override
Definition: Checker.cpp:20
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:458
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:437
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:541
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:336
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:381
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:530
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForLocation(CheckLocationFunc checkfn)
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1540
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:472
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:46
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:1330
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:518
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:138
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)
virtual void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const
See CheckerManager::runCheckersForPrintState.
Definition: Checker.h:489
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:2148
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:535
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:508
TranslationUnitDecl - The top declaration context.
Definition: Decl.h:80
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:421
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:498
void _registerForBind(CheckBindFunc checkfn)
void _dispatchEvent(const EVENT &event) const
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:128