clang 17.0.0git
Checker.h
Go to the documentation of this file.
1//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines Checker, used to create and register checkers.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
14#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
15
20#include "llvm/Support/Casting.h"
21
22namespace clang {
23namespace ento {
24 class BugReporter;
25
26namespace check {
27
28template <typename DECL>
29class 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 }
39public:
40 template <typename CHECKER>
41 static void _register(CHECKER *checker, CheckerManager &mgr) {
43 _checkDecl<CHECKER>),
44 _handlesDecl);
45 }
46};
47
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
55public:
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
72public:
73 template <typename CHECKER>
74 static void _register(CHECKER *checker, CheckerManager &mgr){
77 _checkEndOfTranslationUnit<CHECKER>));
78 }
79};
80
81template <typename STMT>
82class 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 }
91public:
92 template <typename CHECKER>
93 static void _register(CHECKER *checker, CheckerManager &mgr) {
95 _checkStmt<CHECKER>),
96 _handlesStmt);
97 }
98};
99
100template <typename STMT>
101class 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 }
110public:
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
126public:
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
141public:
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
156public:
157 template <typename CHECKER>
158 static void _register(CHECKER *checker, CheckerManager &mgr) {
160 CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
161 }
162};
163
164class 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
171public:
172 template <typename CHECKER>
173 static void _register(CHECKER *checker, CheckerManager &mgr) {
175 CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
176 }
177};
178
179class 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
186public:
187 template <typename CHECKER>
188 static void _register(CHECKER *checker, CheckerManager &mgr) {
190 CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
191 }
192};
193
194class 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
202public:
203 template <typename CHECKER>
204 static void _register(CHECKER *checker, CheckerManager &mgr) {
206 CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
207 }
208};
209
210class 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
218public:
219 template <typename CHECKER>
220 static void _register(CHECKER *checker, CheckerManager &mgr) {
222 CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
223 }
224};
225
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
233public:
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
247public:
248 template <typename CHECKER>
249 static void _register(CHECKER *checker, CheckerManager &mgr) {
251 checker, _checkBeginFunction<CHECKER>));
252 }
253};
254
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
262public:
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
277public:
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 CXXAllocatorCall &Call,
289 CheckerContext &C) {
290 ((const CHECKER *)checker)->checkNewAllocator(Call, C);
291 }
292
293public:
294 template <typename CHECKER>
295 static void _register(CHECKER *checker, CheckerManager &mgr) {
298 _checkNewAllocator<CHECKER>));
299 }
300};
301
303 template <typename CHECKER>
304 static void _checkLiveSymbols(void *checker, ProgramStateRef state,
305 SymbolReaper &SR) {
306 ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
307 }
308
309public:
310 template <typename CHECKER>
311 static void _register(CHECKER *checker, CheckerManager &mgr) {
313 CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
314 }
315};
316
318 template <typename CHECKER>
319 static void _checkDeadSymbols(void *checker,
321 ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
322 }
323
324public:
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,
336 ProgramStateRef state,
337 const InvalidatedSymbols *invalidated,
340 const LocationContext *LCtx,
341 const CallEvent *Call) {
342 return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
343 Explicits, Regions,
344 LCtx, Call);
345 }
346
347public:
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,
360 ProgramStateRef State,
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
390public:
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,
403 ProgramStateRef State,
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
430public:
431 template <typename CHECKER>
432 static void _register(CHECKER *checker, CheckerManager &mgr) {
435 _checkConstPointerEscape<CHECKER>));
436 }
437};
438
439
440template <typename EVENT>
441class Event {
442 template <typename CHECKER>
443 static void _checkEvent(void *checker, const void *event) {
444 ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
445 }
446public:
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
456namespace eval {
457
458class Assume {
459 template <typename CHECKER>
460 static ProgramStateRef _evalAssume(void *checker,
461 ProgramStateRef state,
462 const SVal &cond,
463 bool assumption) {
464 return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
465 }
466
467public:
468 template <typename CHECKER>
469 static void _register(CHECKER *checker, CheckerManager &mgr) {
471 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
472 }
473};
474
475class Call {
476 template <typename CHECKER>
477 static bool _evalCall(void *checker, const CallEvent &Call,
478 CheckerContext &C) {
479 return ((const CHECKER *)checker)->evalCall(Call, C);
480 }
481
482public:
483 template <typename CHECKER>
484 static void _register(CHECKER *checker, CheckerManager &mgr) {
486 CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
487 }
488};
489
490} // end eval namespace
491
493 CheckerNameRef Name;
494 friend class ::clang::ento::CheckerManager;
495
496public:
497 StringRef getTagDescription() const override;
499
500 /// See CheckerManager::runCheckersForPrintState.
501 virtual void printState(raw_ostream &Out, ProgramStateRef State,
502 const char *NL, const char *Sep) const { }
503};
504
505/// Dump checker name to stream.
506raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
507
508/// Tag that can use a checker name as a message provider
509/// (see SimpleProgramPointTag).
511public:
512 CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
513 CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
514};
515
516template <typename CHECK1, typename... CHECKs>
517class Checker : public CHECK1, public CHECKs..., public CheckerBase {
518public:
519 template <typename CHECKER>
520 static void _register(CHECKER *checker, CheckerManager &mgr) {
521 CHECK1::_register(checker, mgr);
522 Checker<CHECKs...>::_register(checker, mgr);
523 }
524};
525
526template <typename CHECK1>
527class Checker<CHECK1> : public CHECK1, public CheckerBase {
528public:
529 template <typename CHECKER>
530 static void _register(CHECKER *checker, CheckerManager &mgr) {
531 CHECK1::_register(checker, mgr);
532 }
533};
534
535template <typename EVENT>
537 CheckerManager *Mgr;
538public:
539 EventDispatcher() : Mgr(nullptr) { }
540
541 template <typename CHECKER>
542 static void _register(CHECKER *checker, CheckerManager &mgr) {
543 mgr._registerDispatcherForEvent<EVENT>();
544 static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
545 }
546
547 void dispatchEvent(const EVENT &event) const {
548 Mgr->_dispatchEvent(event);
549 }
550};
551
552/// We dereferenced a location that may be null.
555 bool IsLoad;
558 // When true, the dereference is in the source code directly. When false, the
559 // dereference might happen later (for example pointer passed to a parameter
560 // that is marked with nonnull attribute.)
562
563 static int Tag;
564};
565
566} // end ento namespace
567
568} // end clang namespace
569
570#endif
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)
Defines the clang::LangOptions interface.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
Definition: ProgramPoint.h:38
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:2837
Stmt - This represents one statement.
Definition: Stmt.h:72
The top declaration context.
Definition: Decl.h:82
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:585
Represents the memory allocation call in a C++ new-expression.
Definition: CallEvent.h:1030
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:149
CheckerNameRef getCheckerName() const
Definition: Checker.cpp:25
virtual void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const
See CheckerManager::runCheckersForPrintState.
Definition: Checker.h:501
StringRef getTagDescription() const override
Definition: Checker.cpp:21
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn)
void _registerForBeginFunction(CheckBeginFunctionFunc checkfn)
void _registerForNewAllocator(CheckNewAllocatorFunc checkfn)
void _registerForPreCall(CheckCallFunc checkfn)
void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn)
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn)
void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn)
CheckerFn< void(const void *event)> CheckEventFunc
void _registerListenerForEvent(CheckEventFunc checkfn)
void _registerForEvalAssume(EvalAssumeFunc checkfn)
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForBody(CheckDeclFunc checkfn)
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn)
void _registerForRegionChanges(CheckRegionChangesFunc checkfn)
void _registerForBind(CheckBindFunc checkfn)
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
void _registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
void _registerForBranchCondition(CheckBranchConditionFunc checkfn)
void _dispatchEvent(const EVENT &event) const
void _registerForEvalCall(EvalCallFunc checkfn)
void _registerForEndFunction(CheckEndFunctionFunc checkfn)
void _registerForLocation(CheckLocationFunc checkfn)
void _registerForPostCall(CheckCallFunc checkfn)
This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
Definition: Checker.h:510
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:530
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:520
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:542
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:547
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:1163
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1570
@ TK_PreserveContents
Tells that a region's contents is not changed.
Definition: MemRegion.h:1585
@ TK_SuppressEscape
Suppress pointer-escaping of a region.
Definition: MemRegion.h:1588
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1731
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:72
A class responsible for cleaning up unused symbols.
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:57
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:41
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:249
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:220
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:279
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:432
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:326
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:235
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:264
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:74
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:448
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:311
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:204
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:295
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:392
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:188
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:158
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:112
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:173
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:128
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:93
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:349
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:469
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:484
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
raw_ostream & operator<<(raw_ostream &Out, const CheckerBase &Checker)
Dump checker name to stream.
Definition: Checker.cpp:35
@ C
Languages that the frontend can parse and compile.
We dereferenced a location that may be null.
Definition: Checker.h:553