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