1//===- CheckerManager.h - Static Analyzer Checker Manager -------*- 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// Defines the Static Analyzer Checker Manager.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
14#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
15
16#include "clang/Analysis/ProgramPoint.h"
17#include "clang/Basic/Diagnostic.h"
18#include "clang/Basic/LangOptions.h"
19#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
20#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
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 <vector>
26
27namespace clang {
28
29class AnalyzerOptions;
30class CallExpr;
31class CXXNewExpr;
32class Decl;
33class LocationContext;
34class Stmt;
35class TranslationUnitDecl;
36
37namespace ento {
38
39class AnalysisManager;
40class BugReporter;
41class CallEvent;
42class CheckerBase;
43class CheckerContext;
44class CheckerRegistry;
45class ExplodedGraph;
46class ExplodedNode;
47class ExplodedNodeSet;
48class ExprEngine;
49class MemRegion;
50struct NodeBuilderContext;
51class ObjCMethodCall;
52class RegionAndSymbolInvalidationTraits;
53class SVal;
54class SymbolReaper;
55
56template <typename T> class CheckerFn;
57
58template <typename RET, typename... Ps>
59class CheckerFn<RET(Ps...)> {
60 using Func = RET (*)(void *, Ps...);
61
62 Func Fn;
63
64public:
65 CheckerBase *Checker;
66
67 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) {}
68
69 RET operator()(Ps... ps) const {
70 return Fn(Checker, ps...);
71 }
72};
73
74/// Describes the different reasons a pointer escapes
75/// during analysis.
76enum PointerEscapeKind {
77 /// A pointer escapes due to binding its value to a location
78 /// that the analyzer cannot track.
79 PSK_EscapeOnBind,
80
81 /// The pointer has been passed to a function call directly.
82 PSK_DirectEscapeOnCall,
83
84 /// The pointer has been passed to a function indirectly.
85 /// For example, the pointer is accessible through an
86 /// argument to a function.
87 PSK_IndirectEscapeOnCall,
88
89
90 /// Escape for a new symbol that was generated into a region
91 /// that the analyzer cannot follow during a conservative call.
92 PSK_EscapeOutParameters,
93
94 /// The reason for pointer escape is unknown. For example,
95 /// a region containing this pointer is invalidated.
96 PSK_EscapeOther
97};
98
99/// This wrapper is used to ensure that only StringRefs originating from the
100/// CheckerRegistry are used as check names. We want to make sure all checker
101/// name strings have a lifetime that keeps them alive at least until the path
102/// diagnostics have been processed, since they are expected to be constexpr
103/// string literals (most likely generated by TblGen).
104class CheckerNameRef {
105 friend class ::clang::ento::CheckerRegistry;
106
107 StringRef Name;
108
109 explicit CheckerNameRef(StringRef Name) : Name(Name) {}
110
111public:
112 CheckerNameRef() = default;
113
114 StringRef getName() const { return Name; }
115 operator StringRef() const { return Name; }
116};
117
118enum class ObjCMessageVisitKind {
119 Pre,
120 Post,
121 MessageNil
122};
123
124class CheckerManager {
125 ASTContext *Context = nullptr;
126 const LangOptions LangOpts;
127 const AnalyzerOptions &AOptions;
128 const Preprocessor *PP = nullptr;
129 CheckerNameRef CurrentCheckerName;
130 DiagnosticsEngine &Diags;
131 std::unique_ptr<CheckerRegistry> Registry;
132
133public:
134 // These constructors are defined in the Frontend library, because
135 // CheckerRegistry, a crucial component of the initialization is in there.
136 // CheckerRegistry cannot be moved to the Core library, because the checker
137 // registration functions are defined in the Checkers library, and the library
138 // dependencies look like this: Core -> Checkers -> Frontend.
139
140 CheckerManager(
141 ASTContext &Context, AnalyzerOptions &AOptions, const Preprocessor &PP,
142 ArrayRef<std::string> plugins,
143 ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns);
144
145 /// Constructs a CheckerManager that ignores all non TblGen-generated
146 /// checkers. Useful for unit testing, unless the checker infrastructure
147 /// itself is tested.
148 CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions,
149 const Preprocessor &PP)
150 : CheckerManager(Context, AOptions, PP, {}, {}) {}
151
152 /// Constructs a CheckerManager without requiring an AST. No checker
153 /// registration will take place. Only useful for retrieving the
154 /// CheckerRegistry and print for help flags where the AST is unavalaible.
155 CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts,
156 DiagnosticsEngine &Diags, ArrayRef<std::string> plugins);
157
158 ~CheckerManager();
159
160 void setCurrentCheckerName(CheckerNameRef name) { CurrentCheckerName = name; }
161 CheckerNameRef getCurrentCheckerName() const { return CurrentCheckerName; }
162
163 bool hasPathSensitiveCheckers() const;
164
165 void finishedCheckerRegistration();
166
167 const LangOptions &getLangOpts() const { return LangOpts; }
168 const AnalyzerOptions &getAnalyzerOptions() const { return AOptions; }
169 const Preprocessor &getPreprocessor() const {
170 assert(PP);
171 return *PP;
172 }
173 const CheckerRegistry &getCheckerRegistry() const { return *Registry; }
174 DiagnosticsEngine &getDiagnostics() const { return Diags; }
175 ASTContext &getASTContext() const {
176 assert(Context);
177 return *Context;
178 }
179
180 /// Emits an error through a DiagnosticsEngine about an invalid user supplied
181 /// checker option value.
182 void reportInvalidCheckerOptionValue(const CheckerBase *C,
183 StringRef OptionName,
184 StringRef ExpectedValueDesc) const;
185
186 using CheckerRef = CheckerBase *;
187 using CheckerTag = const void *;
188 using CheckerDtor = CheckerFn<void ()>;
189
190//===----------------------------------------------------------------------===//
191// Checker registration.
192//===----------------------------------------------------------------------===//
193
194 /// Used to register checkers.
195 /// All arguments are automatically passed through to the checker
196 /// constructor.
197 ///
198 /// \returns a pointer to the checker object.
199 template <typename CHECKER, typename... AT>
200 CHECKER *registerChecker(AT &&... Args) {
201 CheckerTag tag = getTag<CHECKER>();
202 CheckerRef &ref = CheckerTags[tag];
203 assert(!ref && "Checker already registered, use getChecker!");
204
205 CHECKER *checker = new CHECKER(std::forward<AT>(Args)...);
206 checker->Name = CurrentCheckerName;
207 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
208 CHECKER::_register(checker, *this);
209 ref = checker;
210 return checker;
211 }
212
213 template <typename CHECKER>
214 CHECKER *getChecker() {
215 CheckerTag tag = getTag<CHECKER>();
216 assert(CheckerTags.count(tag) != 0 &&
217 "Requested checker is not registered! Maybe you should add it as a "
218 "dependency in Checkers.td?");
219 return static_cast<CHECKER *>(CheckerTags[tag]);
220 }
221
222//===----------------------------------------------------------------------===//
223// Functions for running checkers for AST traversing.
224//===----------------------------------------------------------------------===//
225
226 /// Run checkers handling Decls.
227 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
228 BugReporter &BR);
229
230 /// Run checkers handling Decls containing a Stmt body.
231 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
232 BugReporter &BR);
233
234//===----------------------------------------------------------------------===//
235// Functions for running checkers for path-sensitive checking.
236//===----------------------------------------------------------------------===//
237
238 /// Run checkers for pre-visiting Stmts.
239 ///
240 /// The notification is performed for every explored CFGElement, which does
241 /// not include the control flow statements such as IfStmt.
242 ///
243 /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
244 void runCheckersForPreStmt(ExplodedNodeSet &Dst,
245 const ExplodedNodeSet &Src,
246 const Stmt *S,
247 ExprEngine &Eng) {
248 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
249 }
250
251 /// Run checkers for post-visiting Stmts.
252 ///
253 /// The notification is performed for every explored CFGElement, which does
254 /// not include the control flow statements such as IfStmt.
255 ///
256 /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
257 void runCheckersForPostStmt(ExplodedNodeSet &Dst,
258 const ExplodedNodeSet &Src,
259 const Stmt *S,
260 ExprEngine &Eng,
261 bool wasInlined = false) {
262 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
263 }
264
265 /// Run checkers for visiting Stmts.
266 void runCheckersForStmt(bool isPreVisit,
267 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
268 const Stmt *S, ExprEngine &Eng,
269 bool wasInlined = false);
270
271 /// Run checkers for pre-visiting obj-c messages.
272 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
273 const ExplodedNodeSet &Src,
274 const ObjCMethodCall &msg,
275 ExprEngine &Eng) {
276 runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng);
277 }
278
279 /// Run checkers for post-visiting obj-c messages.
280 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
281 const ExplodedNodeSet &Src,
282 const ObjCMethodCall &msg,
283 ExprEngine &Eng,
284 bool wasInlined = false) {
285 runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng,
286 wasInlined);
287 }
288
289 /// Run checkers for visiting an obj-c message to nil.
290 void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst,
291 const ExplodedNodeSet &Src,
292 const ObjCMethodCall &msg,
293 ExprEngine &Eng) {
294 runCheckersForObjCMessage(ObjCMessageVisitKind::MessageNil, Dst, Src, msg,
295 Eng);
296 }
297
298 /// Run checkers for visiting obj-c messages.
299 void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind,
300 ExplodedNodeSet &Dst,
301 const ExplodedNodeSet &Src,
302 const ObjCMethodCall &msg, ExprEngine &Eng,
303 bool wasInlined = false);
304
305 /// Run checkers for pre-visiting obj-c messages.
306 void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
307 const CallEvent &Call, ExprEngine &Eng) {
308 runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
309 }
310
311 /// Run checkers for post-visiting obj-c messages.
312 void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
313 const CallEvent &Call, ExprEngine &Eng,
314 bool wasInlined = false) {
315 runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
316 wasInlined);
317 }
318
319 /// Run checkers for visiting obj-c messages.
320 void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
321 const ExplodedNodeSet &Src,
322 const CallEvent &Call, ExprEngine &Eng,
323 bool wasInlined = false);
324
325 /// Run checkers for load/store of a location.
326 void runCheckersForLocation(ExplodedNodeSet &Dst,
327 const ExplodedNodeSet &Src,
328 SVal location,
329 bool isLoad,
330 const Stmt *NodeEx,
331 const Stmt *BoundEx,
332 ExprEngine &Eng);
333
334 /// Run checkers for binding of a value to a location.
335 void runCheckersForBind(ExplodedNodeSet &Dst,
336 const ExplodedNodeSet &Src,
337 SVal location, SVal val,
338 const Stmt *S, ExprEngine &Eng,
339 const ProgramPoint &PP);
340
341 /// Run checkers for end of analysis.
342 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
343 ExprEngine &Eng);
344
345 /// Run checkers on beginning of function.
346 void runCheckersForBeginFunction(ExplodedNodeSet &Dst,
347 const BlockEdge &L,
348 ExplodedNode *Pred,
349 ExprEngine &Eng);
350
351 /// Run checkers on end of function.
352 void runCheckersForEndFunction(NodeBuilderContext &BC,
353 ExplodedNodeSet &Dst,
354 ExplodedNode *Pred,
355 ExprEngine &Eng,
356 const ReturnStmt *RS);
357
358 /// Run checkers for branch condition.
359 void runCheckersForBranchCondition(const Stmt *condition,
360 ExplodedNodeSet &Dst, ExplodedNode *Pred,
361 ExprEngine &Eng);
362
363 /// Run checkers between C++ operator new and constructor calls.
364 void runCheckersForNewAllocator(const CXXNewExpr *NE, SVal Target,
365 ExplodedNodeSet &Dst,
366 ExplodedNode *Pred,
367 ExprEngine &Eng,
368 bool wasInlined = false);
369
370 /// Run checkers for live symbols.
371 ///
372 /// Allows modifying SymbolReaper object. For example, checkers can explicitly
373 /// register symbols of interest as live. These symbols will not be marked
374 /// dead and removed.
375 void runCheckersForLiveSymbols(ProgramStateRef state,
376 SymbolReaper &SymReaper);
377
378 /// Run checkers for dead symbols.
379 ///
380 /// Notifies checkers when symbols become dead. For example, this allows
381 /// checkers to aggressively clean up/reduce the checker state and produce
382 /// precise diagnostics.
383 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
384 const ExplodedNodeSet &Src,
385 SymbolReaper &SymReaper, const Stmt *S,
386 ExprEngine &Eng,
387 ProgramPoint::Kind K);
388
389 /// Run checkers for region changes.
390 ///
391 /// This corresponds to the check::RegionChanges callback.
392 /// \param state The current program state.
393 /// \param invalidated A set of all symbols potentially touched by the change.
394 /// \param ExplicitRegions The regions explicitly requested for invalidation.
395 /// For example, in the case of a function call, these would be arguments.
396 /// \param Regions The transitive closure of accessible regions,
397 /// i.e. all regions that may have been touched by this change.
398 /// \param Call The call expression wrapper if the regions are invalidated
399 /// by a call.
400 ProgramStateRef
401 runCheckersForRegionChanges(ProgramStateRef state,
402 const InvalidatedSymbols *invalidated,
403 ArrayRef<const MemRegion *> ExplicitRegions,
404 ArrayRef<const MemRegion *> Regions,
405 const LocationContext *LCtx,
406 const CallEvent *Call);
407
408 /// Run checkers when pointers escape.
409 ///
410 /// This notifies the checkers about pointer escape, which occurs whenever
411 /// the analyzer cannot track the symbol any more. For example, as a
412 /// result of assigning a pointer into a global or when it's passed to a
413 /// function call the analyzer cannot model.
414 ///
415 /// \param State The state at the point of escape.
416 /// \param Escaped The list of escaped symbols.
417 /// \param Call The corresponding CallEvent, if the symbols escape as
418 /// parameters to the given call.
419 /// \param Kind The reason of pointer escape.
420 /// \param ITraits Information about invalidation for a particular
421 /// region/symbol.
422 /// \returns Checkers can modify the state by returning a new one.
423 ProgramStateRef
424 runCheckersForPointerEscape(ProgramStateRef State,
425 const InvalidatedSymbols &Escaped,
426 const CallEvent *Call,
427 PointerEscapeKind Kind,
428 RegionAndSymbolInvalidationTraits *ITraits);
429
430 /// Run checkers for handling assumptions on symbolic values.
431 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
432 SVal Cond, bool Assumption);
433
434 /// Run checkers for evaluating a call.
435 ///
436 /// Warning: Currently, the CallEvent MUST come from a CallExpr!
437 void runCheckersForEvalCall(ExplodedNodeSet &Dst,
438 const ExplodedNodeSet &Src,
439 const CallEvent &CE, ExprEngine &Eng);
440
441 /// Run checkers for the entire Translation Unit.
442 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
443 AnalysisManager &mgr,
444 BugReporter &BR);
445
446 /// Run checkers for debug-printing a ProgramState.
447 ///
448 /// Unlike most other callbacks, any checker can simply implement the virtual
449 /// method CheckerBase::printState if it has custom data to print.
450 ///
451 /// \param Out The output stream
452 /// \param State The state being printed
453 /// \param NL The preferred representation of a newline.
454 /// \param Space The preferred space between the left side and the message.
455 /// \param IsDot Whether the message will be printed in 'dot' format.
456 void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State,
457 const char *NL = "\n",
458 unsigned int Space = 0,
459 bool IsDot = false) const;
460
461 //===----------------------------------------------------------------------===//
462 // Internal registration functions for AST traversing.
463 //===----------------------------------------------------------------------===//
464
465 // Functions used by the registration mechanism, checkers should not touch
466 // these directly.
467
468 using CheckDeclFunc =
469 CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>;
470
471 using HandlesDeclFunc = bool (*)(const Decl *D);
472
473 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
474
475 void _registerForBody(CheckDeclFunc checkfn);
476
477//===----------------------------------------------------------------------===//
478// Internal registration functions for path-sensitive checking.
479//===----------------------------------------------------------------------===//
480
481 using CheckStmtFunc = CheckerFn<void (const Stmt *, CheckerContext &)>;
482
483 using CheckObjCMessageFunc =
484 CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>;
485
486 using CheckCallFunc =
487 CheckerFn<void (const CallEvent &, CheckerContext &)>;
488
489 using CheckLocationFunc =
490 CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S,
491 CheckerContext &)>;
492
493 using CheckBindFunc =
494 CheckerFn<void (const SVal &location, const SVal &val, const Stmt *S,
495 CheckerContext &)>;
496
497 using CheckEndAnalysisFunc =
498 CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>;
499
500 using CheckBeginFunctionFunc = CheckerFn<void (CheckerContext &)>;
501
502 using CheckEndFunctionFunc =
503 CheckerFn<void (const ReturnStmt *, CheckerContext &)>;
504
505 using CheckBranchConditionFunc =
506 CheckerFn<void (const Stmt *, CheckerContext &)>;
507
508 using CheckNewAllocatorFunc =
509 CheckerFn<void (const CXXNewExpr *, SVal, CheckerContext &)>;
510
511 using CheckDeadSymbolsFunc =
512 CheckerFn<void (SymbolReaper &, CheckerContext &)>;
513
514 using CheckLiveSymbolsFunc = CheckerFn<void (ProgramStateRef,SymbolReaper &)>;
515
516 using CheckRegionChangesFunc =
517 CheckerFn<ProgramStateRef (ProgramStateRef,
518 const InvalidatedSymbols *symbols,
519 ArrayRef<const MemRegion *> ExplicitRegions,
520 ArrayRef<const MemRegion *> Regions,
521 const LocationContext *LCtx,
522 const CallEvent *Call)>;
523
524 using CheckPointerEscapeFunc =
525 CheckerFn<ProgramStateRef (ProgramStateRef,
526 const InvalidatedSymbols &Escaped,
527 const CallEvent *Call, PointerEscapeKind Kind,
528 RegionAndSymbolInvalidationTraits *ITraits)>;
529
530 using EvalAssumeFunc =
531 CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond,
532 bool assumption)>;
533
534 using EvalCallFunc = CheckerFn<bool (const CallEvent &, CheckerContext &)>;
535
536 using CheckEndOfTranslationUnit =
537 CheckerFn<void (const TranslationUnitDecl *, AnalysisManager &,
538 BugReporter &)>;
539
540 using HandlesStmtFunc = bool (*)(const Stmt *D);
541
542 void _registerForPreStmt(CheckStmtFunc checkfn,
543 HandlesStmtFunc isForStmtFn);
544 void _registerForPostStmt(CheckStmtFunc checkfn,
545 HandlesStmtFunc isForStmtFn);
546
547 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
548 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
549
550 void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
551
552 void _registerForPreCall(CheckCallFunc checkfn);
553 void _registerForPostCall(CheckCallFunc checkfn);
554
555 void _registerForLocation(CheckLocationFunc checkfn);
556
557 void _registerForBind(CheckBindFunc checkfn);
558
559 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
560
561 void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
562 void _registerForEndFunction(CheckEndFunctionFunc checkfn);
563
564 void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
565
566 void _registerForNewAllocator(CheckNewAllocatorFunc checkfn);
567
568 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
569
570 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
571
572 void _registerForRegionChanges(CheckRegionChangesFunc checkfn);
573
574 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
575
576 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
577
578 void _registerForEvalAssume(EvalAssumeFunc checkfn);
579
580 void _registerForEvalCall(EvalCallFunc checkfn);
581
582 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
583
584//===----------------------------------------------------------------------===//
585// Internal registration functions for events.
586//===----------------------------------------------------------------------===//
587
588 using EventTag = void *;
589 using CheckEventFunc = CheckerFn<void (const void *event)>;
590
591 template <typename EVENT>
592 void _registerListenerForEvent(CheckEventFunc checkfn) {
593 EventInfo &info = Events[&EVENT::Tag];
594 info.Checkers.push_back(checkfn);
595 }
596
597 template <typename EVENT>
598 void _registerDispatcherForEvent() {
599 EventInfo &info = Events[&EVENT::Tag];
600 info.HasDispatcher = true;
601 }
602
603 template <typename EVENT>
604 void _dispatchEvent(const EVENT &event) const {
605 EventsTy::const_iterator I = Events.find(&EVENT::Tag);
606 if (I == Events.end())
607 return;
608 const EventInfo &info = I->second;
609 for (const auto &Checker : info.Checkers)
610 Checker(&event);
611 }
612
613//===----------------------------------------------------------------------===//
614// Implementation details.
615//===----------------------------------------------------------------------===//
616
617private:
618 template <typename CHECKER>
619 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
620
621 template <typename T>
622 static void *getTag() { static int tag; return &tag; }
623
624 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
625
626 std::vector<CheckerDtor> CheckerDtors;
627
628 struct DeclCheckerInfo {
629 CheckDeclFunc CheckFn;
630 HandlesDeclFunc IsForDeclFn;
631 };
632 std::vector<DeclCheckerInfo> DeclCheckers;
633
634 std::vector<CheckDeclFunc> BodyCheckers;
635
636 using CachedDeclCheckers = SmallVector<CheckDeclFunc, 4>;
637 using CachedDeclCheckersMapTy = llvm::DenseMap<unsigned, CachedDeclCheckers>;
638 CachedDeclCheckersMapTy CachedDeclCheckersMap;
639
640 struct StmtCheckerInfo {
641 CheckStmtFunc CheckFn;
642 HandlesStmtFunc IsForStmtFn;
643 bool IsPreVisit;
644 };
645 std::vector<StmtCheckerInfo> StmtCheckers;
646
647 using CachedStmtCheckers = SmallVector<CheckStmtFunc, 4>;
648 using CachedStmtCheckersMapTy = llvm::DenseMap<unsigned, CachedStmtCheckers>;
649 CachedStmtCheckersMapTy CachedStmtCheckersMap;
650
651 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
652 bool isPreVisit);
653
654 /// Returns the checkers that have registered for callbacks of the
655 /// given \p Kind.
656 const std::vector<CheckObjCMessageFunc> &
657 getObjCMessageCheckers(ObjCMessageVisitKind Kind) const;
658
659 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
660 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
661 std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
662
663 std::vector<CheckCallFunc> PreCallCheckers;
664 std::vector<CheckCallFunc> PostCallCheckers;
665
666 std::vector<CheckLocationFunc> LocationCheckers;
667
668 std::vector<CheckBindFunc> BindCheckers;
669
670 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
671
672 std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers;
673 std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
674
675 std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
676
677 std::vector<CheckNewAllocatorFunc> NewAllocatorCheckers;
678
679 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
680
681 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
682
683 std::vector<CheckRegionChangesFunc> RegionChangesCheckers;
684
685 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
686
687 std::vector<EvalAssumeFunc> EvalAssumeCheckers;
688
689 std::vector<EvalCallFunc> EvalCallCheckers;
690
691 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
692
693 struct EventInfo {
694 SmallVector<CheckEventFunc, 4> Checkers;
695 bool HasDispatcher = false;
696
697 EventInfo() = default;
698 };
699
700 using EventsTy = llvm::DenseMap<EventTag, EventInfo>;
701 EventsTy Events;
702};
703
704} // namespace ento
705
706} // namespace clang
707
708#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
709