clang: include/clang/StaticAnalyzer/Core/CheckerManager.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
14#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
15
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/StringRef.h"
25#include
26
28
29class AnalyzerOptions;
30class CallExpr;
32class LocationContext;
33class Stmt;
34class TranslationUnitDecl;
35
36namespace ento {
37
38class AnalysisManager;
39class CXXAllocatorCall;
40class BugReporter;
41class CallEvent;
42class CheckerBase;
43class CheckerContext;
44class CheckerRegistry;
45struct CheckerRegistryData;
46class ExplodedGraph;
47class ExplodedNode;
48class ExplodedNodeSet;
49class ExprEngine;
50struct EvalCallOptions;
51class MemRegion;
52class NodeBuilderContext;
53class ObjCMethodCall;
54class RegionAndSymbolInvalidationTraits;
55class SVal;
56class SymbolReaper;
57
59
60template <typename RET, typename... Ps>
62 using Func = RET (*)(void *, Ps...);
63
64 Func Fn;
65
66public:
68
70
72 return Fn(Checker, ps...);
73 }
74};
75
76
77
79
80
82
83
85
86
87
88
90
91
92
93
95
96
97
100
101
102
103
104
105
107 friend class ::clang::ento::CheckerRegistry;
108
109 StringRef Name;
110
111 explicit CheckerNameRef(StringRef Name) : Name(Name) {}
112
113public:
115
116 StringRef getName() const { return Name; }
117 operator StringRef() const { return Name; }
118};
119
124};
125
133 std::unique_ptr RegistryData;
134
135public:
136
137
138
139
140
141
146
147
148
149
153
154
155
156
157 CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts,
158 DiagnosticsEngine &Diags, ArrayRefstd::string plugins);
159
161
164
166
170 assert(PP);
171 return *PP;
172 }
174 return *RegistryData;
175 }
178 assert(Context);
179 return *Context;
180 }
181
182
183
185 StringRef OptionName,
186 StringRef ExpectedValueDesc) const;
187
191
192
193
194
195
196
197
198
199
200
201 template <typename CHECKER, typename... AT>
205 assert(!ref && "Checker already registered, use getChecker!");
206
207 CHECKER *checker = new CHECKER(std::forward(Args)...);
208 checker->Name = CurrentCheckerName;
209 CheckerDtors.push_back(CheckerDtor(checker, destruct));
210 CHECKER::_register(checker, *this);
211 ref = checker;
212 return checker;
213 }
214
215 template
218 assert(CheckerTags.count(tag) != 0 &&
219 "Requested checker is not registered! Maybe you should add it as a "
220 "dependency in Checkers.td?");
221 return static_cast<CHECKER *>(CheckerTags[tag]);
222 }
223
225 return CheckerTags.contains(getTag());
226 }
227
228
229
230
231
232
235
236
239
240
241
242
243
244
245
246
247
248
249
252 const Stmt *S,
255 }
256
257
258
259
260
261
262
265 const Stmt *S,
267 bool wasInlined = false) {
268 runCheckersForStmt(false, Dst, Src, S, Eng, wasInlined);
269 }
270
271
275 bool wasInlined = false);
276
277
283 }
284
285
290 bool wasInlined = false) {
292 wasInlined);
293 }
294
295
301 Eng);
302 }
303
304
309 bool wasInlined = false);
310
311
315 }
316
317
320 bool wasInlined = false) {
322 wasInlined);
323 }
324
325
329 bool wasInlined = false);
330
331
334 SVal location,
335 bool isLoad,
336 const Stmt *NodeEx,
337 const Stmt *BoundEx,
339
340
346
347
350
351
356
357
363
364
368
369
372 ExprEngine &Eng, bool wasInlined = false);
373
374
375
376
377
378
381
382
383
384
385
386
392
393
394
395
396
397
398
399
400
401
402
403
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
433
434
436 SVal Cond, bool Assumption);
437
438
439
440
444
445
449
450
451
452
453
454
455
456
457
458
459
461 const char *NL = "\n",
462 unsigned int Space = 0,
463 bool IsDot = false) const;
464
465
466
467
468
469
470
471
474
476
478
480
481
482
483
484
486
489
492
495
498
501
503
506
509
512
515
517
525
531
534
536
540
542
547
550
552
555
557
559
561
564
566
568
570
572
574
576
578
580
582
584
585
586
587
588
591
592 template
594 EventInfo &info = Events[&EVENT::Tag];
595 info.Checkers.push_back(checkfn);
596 }
597
598 template
600 EventInfo &info = Events[&EVENT::Tag];
601 info.HasDispatcher = true;
602 }
603
604 template
606 EventsTy::const_iterator I = Events.find(&EVENT::Tag);
607 if (I == Events.end())
608 return;
609 const EventInfo &info = I->second;
610 for (const auto &Checker : info.Checkers)
612 }
613
614
615
616
617
618private:
619 template
620 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
621
622 template
623 static void *getTag() { static int tag; return &tag; }
624
625 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
626
627 std::vector CheckerDtors;
628
629 struct DeclCheckerInfo {
632 };
633 std::vector DeclCheckers;
634
635 std::vector BodyCheckers;
636
637 using CachedDeclCheckers = SmallVector<CheckDeclFunc, 4>;
638 using CachedDeclCheckersMapTy = llvm::DenseMap<unsigned, CachedDeclCheckers>;
639 CachedDeclCheckersMapTy CachedDeclCheckersMap;
640
641 struct StmtCheckerInfo {
644 bool IsPreVisit;
645 };
646 std::vector StmtCheckers;
647
648 using CachedStmtCheckers = SmallVector<CheckStmtFunc, 4>;
649 using CachedStmtCheckersMapTy = llvm::DenseMap<unsigned, CachedStmtCheckers>;
650 CachedStmtCheckersMapTy CachedStmtCheckersMap;
651
652 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
653 bool isPreVisit);
654
655
656
657 const std::vector &
659
660 std::vector PreObjCMessageCheckers;
661 std::vector PostObjCMessageCheckers;
662 std::vector ObjCMessageNilCheckers;
663
664 std::vector PreCallCheckers;
665 std::vector PostCallCheckers;
666
667 std::vector LocationCheckers;
668
669 std::vector BindCheckers;
670
671 std::vector EndAnalysisCheckers;
672
673 std::vector BeginFunctionCheckers;
674 std::vector EndFunctionCheckers;
675
676 std::vector BranchConditionCheckers;
677
678 std::vector NewAllocatorCheckers;
679
680 std::vector LiveSymbolsCheckers;
681
682 std::vector DeadSymbolsCheckers;
683
684 std::vector RegionChangesCheckers;
685
686 std::vector PointerEscapeCheckers;
687
688 std::vector EvalAssumeCheckers;
689
690 std::vector EvalCallCheckers;
691
692 std::vector EndOfTranslationUnitCheckers;
693
694 struct EventInfo {
695 SmallVector<CheckEventFunc, 4> Checkers;
696 bool HasDispatcher = false;
697
698 EventInfo() = default;
699 };
700
701 using EventsTy = llvm::DenseMap<EventTag, EventInfo>;
702 EventsTy Events;
703};
704
705}
706
707}
708
709#endif
Defines the Diagnostic-related interfaces.
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
Defines the clang::LangOptions interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Stores options for the analyzer from the command line.
Decl - This represents one declaration (or definition), e.g.
Concrete class used by the front-end to report problems and issues.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Stmt - This represents one statement.
The top declaration context.
BugReporter is a utility class for generating PathDiagnostics for analysis.
Represents the memory allocation call in a C++ new-expression.
Represents an abstract call to a function or method along a particular path.
CheckerFn(CheckerBase *checker, Func fn)
RET operator()(Ps... ps) const
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn)
const AnalyzerOptions & getAnalyzerOptions() const
void _registerForBeginFunction(CheckBeginFunctionFunc checkfn)
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
void _registerForNewAllocator(CheckNewAllocatorFunc checkfn)
void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
void _registerForPreCall(CheckCallFunc checkfn)
void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn)
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
bool(*)(const Decl *D) HandlesDeclFunc
void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for visiting obj-c messages.
void runCheckersOnASTDecl(const Decl *D, AnalysisManager &mgr, BugReporter &BR)
Run checkers handling Decls.
void reportInvalidCheckerOptionValue(const CheckerBase *C, StringRef OptionName, StringRef ExpectedValueDesc) const
Emits an error through a DiagnosticsEngine about an invalid user supplied checker option value.
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn)
void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn)
void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR)
Run checkers for the entire Translation Unit.
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
ASTContext & getASTContext() const
void _registerListenerForEvent(CheckEventFunc checkfn)
void _registerForEvalAssume(EvalAssumeFunc checkfn)
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForBody(CheckDeclFunc checkfn)
DiagnosticsEngine & getDiagnostics() const
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
const CheckerRegistryData & getCheckerRegistryData() const
CheckerFn< void(const Stmt *, CheckerContext &)> CheckStmtFunc
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions, const Preprocessor &PP)
Constructs a CheckerManager that ignores all non TblGen-generated checkers.
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
CheckerFn< void(const Decl *, AnalysisManager &, BugReporter &)> CheckDeclFunc
void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
Run checkers for debug-printing a ProgramState.
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn)
void _registerForRegionChanges(CheckRegionChangesFunc checkfn)
bool hasPathSensitiveCheckers() const
void _registerForBind(CheckBindFunc checkfn)
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng, const EvalCallOptions &CallOpts)
Run checkers for evaluating a call.
void _registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void _registerForBranchCondition(CheckBranchConditionFunc checkfn)
void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng)
Run checkers for visiting an obj-c message to nil.
void _dispatchEvent(const EVENT &event) const
void runCheckersForStmt(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for visiting Stmts.
const LangOptions & getLangOpts() const
void _registerForEvalCall(EvalCallFunc checkfn)
void _registerForEndFunction(CheckEndFunctionFunc checkfn)
void _registerDispatcherForEvent()
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
CheckerNameRef getCurrentCheckerName() const
CheckerFn< void()> CheckerDtor
bool isRegisteredChecker()
void _registerForLocation(CheckLocationFunc checkfn)
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn)
void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for visiting obj-c messages.
bool(*)(const Stmt *D) HandlesStmtFunc
void _registerForPostCall(CheckCallFunc checkfn)
void runCheckersOnASTBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR)
Run checkers handling Decls containing a Stmt body.
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
void setCurrentCheckerName(CheckerNameRef name)
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
const Preprocessor & getPreprocessor() const
This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...
StringRef getName() const
Manages a set of available checkers for running a static analysis.
Represents any expression that calls an Objective-C method.
Information about invalidation for a particular region/symbol.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
A class responsible for cleaning up unused symbols.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
@ PSK_DirectEscapeOnCall
The pointer has been passed to a function call directly.
@ PSK_EscapeOnBind
A pointer escapes due to binding its value to a location that the analyzer cannot track.
@ PSK_IndirectEscapeOnCall
The pointer has been passed to a function indirectly.
@ PSK_EscapeOther
The reason for pointer escape is unknown.
@ PSK_EscapeOutParameters
Escape for a new symbol that was generated into a region that the analyzer cannot follow during a con...
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
llvm::DenseSet< SymbolRef > InvalidatedSymbols
The JSON file list parser is used to communicate input to InstallAPI.
Hints for figuring out of a call should be inlined during evalCall().