clang 19.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, SVal location, bool isLoad,
197 const Stmt *S, CheckerContext &C) {
198 ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
199 }
200
201public:
202 template <typename CHECKER>
203 static void _register(CHECKER *checker, CheckerManager &mgr) {
205 CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
206 }
207};
208
209class Bind {
210 template <typename CHECKER>
211 static void _checkBind(void *checker, SVal location, SVal val, const Stmt *S,
212 CheckerContext &C) {
213 ((const CHECKER *)checker)->checkBind(location, val, S, C);
214 }
215
216public:
217 template <typename CHECKER>
218 static void _register(CHECKER *checker, CheckerManager &mgr) {
220 CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
221 }
222};
223
225 template <typename CHECKER>
226 static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
227 BugReporter &BR, ExprEngine &Eng) {
228 ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
229 }
230
231public:
232 template <typename CHECKER>
233 static void _register(CHECKER *checker, CheckerManager &mgr) {
235 CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
236 }
237};
238
240 template <typename CHECKER>
241 static void _checkBeginFunction(void *checker, CheckerContext &C) {
242 ((const CHECKER *)checker)->checkBeginFunction(C);
243 }
244
245public:
246 template <typename CHECKER>
247 static void _register(CHECKER *checker, CheckerManager &mgr) {
249 checker, _checkBeginFunction<CHECKER>));
250 }
251};
252
254 template <typename CHECKER>
255 static void _checkEndFunction(void *checker, const ReturnStmt *RS,
256 CheckerContext &C) {
257 ((const CHECKER *)checker)->checkEndFunction(RS, C);
258 }
259
260public:
261 template <typename CHECKER>
262 static void _register(CHECKER *checker, CheckerManager &mgr) {
264 CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
265 }
266};
267
269 template <typename CHECKER>
270 static void _checkBranchCondition(void *checker, const Stmt *Condition,
271 CheckerContext & C) {
272 ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
273 }
274
275public:
276 template <typename CHECKER>
277 static void _register(CHECKER *checker, CheckerManager &mgr) {
280 _checkBranchCondition<CHECKER>));
281 }
282};
283
285 template <typename CHECKER>
286 static void _checkNewAllocator(void *checker, const CXXAllocatorCall &Call,
287 CheckerContext &C) {
288 ((const CHECKER *)checker)->checkNewAllocator(Call, C);
289 }
290
291public:
292 template <typename CHECKER>
293 static void _register(CHECKER *checker, CheckerManager &mgr) {
296 _checkNewAllocator<CHECKER>));
297 }
298};
299
301 template <typename CHECKER>
302 static void _checkLiveSymbols(void *checker, ProgramStateRef state,
303 SymbolReaper &SR) {
304 ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
305 }
306
307public:
308 template <typename CHECKER>
309 static void _register(CHECKER *checker, CheckerManager &mgr) {
311 CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
312 }
313};
314
316 template <typename CHECKER>
317 static void _checkDeadSymbols(void *checker,
319 ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
320 }
321
322public:
323 template <typename CHECKER>
324 static void _register(CHECKER *checker, CheckerManager &mgr) {
326 CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
327 }
328};
329
331 template <typename CHECKER>
332 static ProgramStateRef
333 _checkRegionChanges(void *checker,
334 ProgramStateRef state,
335 const InvalidatedSymbols *invalidated,
338 const LocationContext *LCtx,
339 const CallEvent *Call) {
340 return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
341 Explicits, Regions,
342 LCtx, Call);
343 }
344
345public:
346 template <typename CHECKER>
347 static void _register(CHECKER *checker, CheckerManager &mgr) {
350 _checkRegionChanges<CHECKER>));
351 }
352};
353
355 template <typename CHECKER>
356 static ProgramStateRef
357 _checkPointerEscape(void *Checker,
358 ProgramStateRef State,
359 const InvalidatedSymbols &Escaped,
360 const CallEvent *Call,
363
364 if (!ETraits)
365 return ((const CHECKER *)Checker)->checkPointerEscape(State,
366 Escaped,
367 Call,
368 Kind);
369
370 InvalidatedSymbols RegularEscape;
371 for (SymbolRef Sym : Escaped)
372 if (!ETraits->hasTrait(
374 !ETraits->hasTrait(
376 RegularEscape.insert(Sym);
377
378 if (RegularEscape.empty())
379 return State;
380
381 return ((const CHECKER *)Checker)->checkPointerEscape(State,
382 RegularEscape,
383 Call,
384 Kind);
385 }
386
387public:
388 template <typename CHECKER>
389 static void _register(CHECKER *checker, CheckerManager &mgr) {
392 _checkPointerEscape<CHECKER>));
393 }
394};
395
397 template <typename CHECKER>
398 static ProgramStateRef
399 _checkConstPointerEscape(void *Checker,
400 ProgramStateRef State,
401 const InvalidatedSymbols &Escaped,
402 const CallEvent *Call,
405
406 if (!ETraits)
407 return State;
408
409 InvalidatedSymbols ConstEscape;
410 for (SymbolRef Sym : Escaped) {
411 if (ETraits->hasTrait(
413 !ETraits->hasTrait(
415 ConstEscape.insert(Sym);
416 }
417
418 if (ConstEscape.empty())
419 return State;
420
421 return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
422 ConstEscape,
423 Call,
424 Kind);
425 }
426
427public:
428 template <typename CHECKER>
429 static void _register(CHECKER *checker, CheckerManager &mgr) {
432 _checkConstPointerEscape<CHECKER>));
433 }
434};
435
436
437template <typename EVENT>
438class Event {
439 template <typename CHECKER>
440 static void _checkEvent(void *checker, const void *event) {
441 ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
442 }
443public:
444 template <typename CHECKER>
445 static void _register(CHECKER *checker, CheckerManager &mgr) {
446 mgr._registerListenerForEvent<EVENT>(
447 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
448 }
449};
450
451} // end check namespace
452
453namespace eval {
454
455class Assume {
456 template <typename CHECKER>
457 static ProgramStateRef _evalAssume(void *checker, ProgramStateRef state,
458 SVal cond, bool assumption) {
459 return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
460 }
461
462public:
463 template <typename CHECKER>
464 static void _register(CHECKER *checker, CheckerManager &mgr) {
466 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
467 }
468};
469
470class Call {
471 template <typename CHECKER>
472 static bool _evalCall(void *checker, const CallEvent &Call,
473 CheckerContext &C) {
474 return ((const CHECKER *)checker)->evalCall(Call, C);
475 }
476
477public:
478 template <typename CHECKER>
479 static void _register(CHECKER *checker, CheckerManager &mgr) {
481 CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
482 }
483};
484
485} // end eval namespace
486
488 CheckerNameRef Name;
489 friend class ::clang::ento::CheckerManager;
490
491public:
492 StringRef getTagDescription() const override;
494
495 /// See CheckerManager::runCheckersForPrintState.
496 virtual void printState(raw_ostream &Out, ProgramStateRef State,
497 const char *NL, const char *Sep) const { }
498};
499
500/// Dump checker name to stream.
501raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
502
503/// Tag that can use a checker name as a message provider
504/// (see SimpleProgramPointTag).
506public:
507 CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
508 CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
509};
510
511template <typename CHECK1, typename... CHECKs>
512class Checker : public CHECK1, public CHECKs..., public CheckerBase {
513public:
514 template <typename CHECKER>
515 static void _register(CHECKER *checker, CheckerManager &mgr) {
516 CHECK1::_register(checker, mgr);
517 Checker<CHECKs...>::_register(checker, mgr);
518 }
519};
520
521template <typename CHECK1>
522class Checker<CHECK1> : public CHECK1, public CheckerBase {
523public:
524 template <typename CHECKER>
525 static void _register(CHECKER *checker, CheckerManager &mgr) {
526 CHECK1::_register(checker, mgr);
527 }
528};
529
530template <typename EVENT>
532 CheckerManager *Mgr = nullptr;
533public:
534 EventDispatcher() = default;
535
536 template <typename CHECKER>
537 static void _register(CHECKER *checker, CheckerManager &mgr) {
538 mgr._registerDispatcherForEvent<EVENT>();
539 static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
540 }
541
542 void dispatchEvent(const EVENT &event) const {
543 Mgr->_dispatchEvent(event);
544 }
545};
546
547/// We dereferenced a location that may be null.
550 bool IsLoad;
553 // When true, the dereference is in the source code directly. When false, the
554 // dereference might happen later (for example pointer passed to a parameter
555 // that is marked with nonnull attribute.)
557
558 static int Tag;
559};
560
561} // end ento namespace
562
563} // end clang namespace
564
565#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:86
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:3019
Stmt - This represents one statement.
Definition: Stmt.h:84
The top declaration context.
Definition: Decl.h:84
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:1112
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:153
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:496
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:505
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:525
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:515
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:537
void dispatchEvent(const EVENT &event) const
Definition: Checker.h:542
Represents any expression that calls an Objective-C method.
Definition: CallEvent.h:1243
Information about invalidation for a particular region/symbol.
Definition: MemRegion.h:1624
@ TK_PreserveContents
Tells that a region's contents is not changed.
Definition: MemRegion.h:1639
@ TK_SuppressEscape
Suppress pointer-escaping of a region.
Definition: MemRegion.h:1642
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
Definition: MemRegion.cpp:1784
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:55
Symbolic value.
Definition: SymExpr.h:30
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:247
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:218
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:277
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:429
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:324
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:233
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:262
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:74
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:445
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:309
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:203
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:293
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:143
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:389
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:347
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:464
static void _register(CHECKER *checker, CheckerManager &mgr)
Definition: Checker.h:479
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
The JSON file list parser is used to communicate input to InstallAPI.
We dereferenced a location that may be null.
Definition: Checker.h:548