1221339Sdim//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=// 2221339Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6221339Sdim// 7221339Sdim//===----------------------------------------------------------------------===// 8221339Sdim// 9221339Sdim// This file defines Checker, used to create and register checkers. 10221339Sdim// 11221339Sdim//===----------------------------------------------------------------------===// 12221339Sdim 13280031Sdim#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H 14280031Sdim#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H 15221339Sdim 16226633Sdim#include "clang/Analysis/ProgramPoint.h" 17353358Sdim#include "clang/Basic/LangOptions.h" 18221339Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h" 19221339Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 20221339Sdim#include "llvm/Support/Casting.h" 21221339Sdim 22221339Sdimnamespace clang { 23221339Sdimnamespace ento { 24221339Sdim class BugReporter; 25221339Sdim 26221339Sdimnamespace check { 27221339Sdim 28221339Sdimtemplate <typename DECL> 29221339Sdimclass ASTDecl { 30221339Sdim template <typename CHECKER> 31221339Sdim static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr, 32221339Sdim BugReporter &BR) { 33249423Sdim ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR); 34221339Sdim } 35221339Sdim 36221339Sdim static bool _handlesDecl(const Decl *D) { 37249423Sdim return isa<DECL>(D); 38221339Sdim } 39221339Sdimpublic: 40221339Sdim template <typename CHECKER> 41221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 42221339Sdim mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker, 43221339Sdim _checkDecl<CHECKER>), 44221339Sdim _handlesDecl); 45221339Sdim } 46221339Sdim}; 47221339Sdim 48221339Sdimclass ASTCodeBody { 49221339Sdim template <typename CHECKER> 50221339Sdim static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr, 51221339Sdim BugReporter &BR) { 52221339Sdim ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR); 53221339Sdim } 54221339Sdim 55221339Sdimpublic: 56221339Sdim template <typename CHECKER> 57221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 58221339Sdim mgr._registerForBody(CheckerManager::CheckDeclFunc(checker, 59221339Sdim _checkBody<CHECKER>)); 60221339Sdim } 61221339Sdim}; 62221339Sdim 63223017Sdimclass EndOfTranslationUnit { 64223017Sdim template <typename CHECKER> 65223017Sdim static void _checkEndOfTranslationUnit(void *checker, 66341825Sdim const TranslationUnitDecl *TU, 67223017Sdim AnalysisManager& mgr, 68223017Sdim BugReporter &BR) { 69223017Sdim ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR); 70223017Sdim } 71223017Sdim 72223017Sdimpublic: 73223017Sdim template <typename CHECKER> 74223017Sdim static void _register(CHECKER *checker, CheckerManager &mgr){ 75223017Sdim mgr._registerForEndOfTranslationUnit( 76223017Sdim CheckerManager::CheckEndOfTranslationUnit(checker, 77223017Sdim _checkEndOfTranslationUnit<CHECKER>)); 78223017Sdim } 79223017Sdim}; 80223017Sdim 81221339Sdimtemplate <typename STMT> 82221339Sdimclass PreStmt { 83221339Sdim template <typename CHECKER> 84221339Sdim static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { 85249423Sdim ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C); 86221339Sdim } 87221339Sdim 88221339Sdim static bool _handlesStmt(const Stmt *S) { 89249423Sdim return isa<STMT>(S); 90221339Sdim } 91221339Sdimpublic: 92221339Sdim template <typename CHECKER> 93221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 94221339Sdim mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker, 95221339Sdim _checkStmt<CHECKER>), 96221339Sdim _handlesStmt); 97221339Sdim } 98221339Sdim}; 99221339Sdim 100221339Sdimtemplate <typename STMT> 101221339Sdimclass PostStmt { 102221339Sdim template <typename CHECKER> 103221339Sdim static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { 104249423Sdim ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C); 105221339Sdim } 106221339Sdim 107221339Sdim static bool _handlesStmt(const Stmt *S) { 108249423Sdim return isa<STMT>(S); 109221339Sdim } 110221339Sdimpublic: 111221339Sdim template <typename CHECKER> 112221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 113221339Sdim mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker, 114221339Sdim _checkStmt<CHECKER>), 115221339Sdim _handlesStmt); 116221339Sdim } 117221339Sdim}; 118221339Sdim 119221339Sdimclass PreObjCMessage { 120221339Sdim template <typename CHECKER> 121239462Sdim static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, 122221339Sdim CheckerContext &C) { 123221339Sdim ((const CHECKER *)checker)->checkPreObjCMessage(msg, C); 124221339Sdim } 125221339Sdim 126221339Sdimpublic: 127221339Sdim template <typename CHECKER> 128221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 129221339Sdim mgr._registerForPreObjCMessage( 130221339Sdim CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>)); 131221339Sdim } 132221339Sdim}; 133221339Sdim 134296417Sdimclass ObjCMessageNil { 135296417Sdim template <typename CHECKER> 136296417Sdim static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, 137296417Sdim CheckerContext &C) { 138296417Sdim ((const CHECKER *)checker)->checkObjCMessageNil(msg, C); 139296417Sdim } 140296417Sdim 141296417Sdimpublic: 142296417Sdim template <typename CHECKER> 143296417Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 144296417Sdim mgr._registerForObjCMessageNil( 145296417Sdim CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>)); 146296417Sdim } 147296417Sdim}; 148296417Sdim 149221339Sdimclass PostObjCMessage { 150221339Sdim template <typename CHECKER> 151239462Sdim static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, 152221339Sdim CheckerContext &C) { 153221339Sdim ((const CHECKER *)checker)->checkPostObjCMessage(msg, C); 154221339Sdim } 155221339Sdim 156221339Sdimpublic: 157221339Sdim template <typename CHECKER> 158221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 159221339Sdim mgr._registerForPostObjCMessage( 160221339Sdim CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>)); 161221339Sdim } 162221339Sdim}; 163221339Sdim 164239462Sdimclass PreCall { 165239462Sdim template <typename CHECKER> 166239462Sdim static void _checkCall(void *checker, const CallEvent &msg, 167239462Sdim CheckerContext &C) { 168239462Sdim ((const CHECKER *)checker)->checkPreCall(msg, C); 169239462Sdim } 170239462Sdim 171239462Sdimpublic: 172239462Sdim template <typename CHECKER> 173239462Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 174239462Sdim mgr._registerForPreCall( 175239462Sdim CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>)); 176239462Sdim } 177239462Sdim}; 178239462Sdim 179239462Sdimclass PostCall { 180239462Sdim template <typename CHECKER> 181239462Sdim static void _checkCall(void *checker, const CallEvent &msg, 182239462Sdim CheckerContext &C) { 183239462Sdim ((const CHECKER *)checker)->checkPostCall(msg, C); 184239462Sdim } 185239462Sdim 186239462Sdimpublic: 187239462Sdim template <typename CHECKER> 188239462Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 189239462Sdim mgr._registerForPostCall( 190239462Sdim CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>)); 191239462Sdim } 192239462Sdim}; 193239462Sdim 194221339Sdimclass Location { 195221339Sdim template <typename CHECKER> 196226633Sdim static void _checkLocation(void *checker, 197226633Sdim const SVal &location, bool isLoad, const Stmt *S, 198221339Sdim CheckerContext &C) { 199226633Sdim ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C); 200221339Sdim } 201221339Sdim 202221339Sdimpublic: 203221339Sdim template <typename CHECKER> 204221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 205221339Sdim mgr._registerForLocation( 206221339Sdim CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>)); 207221339Sdim } 208221339Sdim}; 209221339Sdim 210221339Sdimclass Bind { 211221339Sdim template <typename CHECKER> 212226633Sdim static void _checkBind(void *checker, 213226633Sdim const SVal &location, const SVal &val, const Stmt *S, 214221339Sdim CheckerContext &C) { 215226633Sdim ((const CHECKER *)checker)->checkBind(location, val, S, C); 216221339Sdim } 217221339Sdim 218221339Sdimpublic: 219221339Sdim template <typename CHECKER> 220221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 221221339Sdim mgr._registerForBind( 222221339Sdim CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>)); 223221339Sdim } 224221339Sdim}; 225221339Sdim 226221339Sdimclass EndAnalysis { 227221339Sdim template <typename CHECKER> 228221339Sdim static void _checkEndAnalysis(void *checker, ExplodedGraph &G, 229221339Sdim BugReporter &BR, ExprEngine &Eng) { 230221339Sdim ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng); 231221339Sdim } 232221339Sdim 233221339Sdimpublic: 234221339Sdim template <typename CHECKER> 235221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 236221339Sdim mgr._registerForEndAnalysis( 237221339Sdim CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>)); 238221339Sdim } 239221339Sdim}; 240221339Sdim 241309124Sdimclass BeginFunction { 242309124Sdim template <typename CHECKER> 243309124Sdim static void _checkBeginFunction(void *checker, CheckerContext &C) { 244309124Sdim ((const CHECKER *)checker)->checkBeginFunction(C); 245309124Sdim } 246309124Sdim 247309124Sdimpublic: 248309124Sdim template <typename CHECKER> 249309124Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 250309124Sdim mgr._registerForBeginFunction(CheckerManager::CheckBeginFunctionFunc( 251309124Sdim checker, _checkBeginFunction<CHECKER>)); 252309124Sdim } 253309124Sdim}; 254309124Sdim 255249423Sdimclass EndFunction { 256221339Sdim template <typename CHECKER> 257341825Sdim static void _checkEndFunction(void *checker, const ReturnStmt *RS, 258249423Sdim CheckerContext &C) { 259341825Sdim ((const CHECKER *)checker)->checkEndFunction(RS, C); 260221339Sdim } 261221339Sdim 262221339Sdimpublic: 263221339Sdim template <typename CHECKER> 264221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 265249423Sdim mgr._registerForEndFunction( 266249423Sdim CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>)); 267221339Sdim } 268221339Sdim}; 269221339Sdim 270221339Sdimclass BranchCondition { 271221339Sdim template <typename CHECKER> 272234353Sdim static void _checkBranchCondition(void *checker, const Stmt *Condition, 273234353Sdim CheckerContext & C) { 274234353Sdim ((const CHECKER *)checker)->checkBranchCondition(Condition, C); 275221339Sdim } 276221339Sdim 277221339Sdimpublic: 278221339Sdim template <typename CHECKER> 279221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 280221339Sdim mgr._registerForBranchCondition( 281221339Sdim CheckerManager::CheckBranchConditionFunc(checker, 282221339Sdim _checkBranchCondition<CHECKER>)); 283221339Sdim } 284221339Sdim}; 285221339Sdim 286341825Sdimclass NewAllocator { 287341825Sdim template <typename CHECKER> 288341825Sdim static void _checkNewAllocator(void *checker, const CXXNewExpr *NE, 289341825Sdim SVal Target, CheckerContext &C) { 290341825Sdim ((const CHECKER *)checker)->checkNewAllocator(NE, Target, C); 291341825Sdim } 292341825Sdim 293341825Sdimpublic: 294341825Sdim template <typename CHECKER> 295341825Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 296341825Sdim mgr._registerForNewAllocator( 297341825Sdim CheckerManager::CheckNewAllocatorFunc(checker, 298341825Sdim _checkNewAllocator<CHECKER>)); 299341825Sdim } 300341825Sdim}; 301341825Sdim 302221339Sdimclass LiveSymbols { 303221339Sdim template <typename CHECKER> 304234353Sdim static void _checkLiveSymbols(void *checker, ProgramStateRef state, 305221339Sdim SymbolReaper &SR) { 306221339Sdim ((const CHECKER *)checker)->checkLiveSymbols(state, SR); 307221339Sdim } 308221339Sdim 309221339Sdimpublic: 310221339Sdim template <typename CHECKER> 311221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 312221339Sdim mgr._registerForLiveSymbols( 313221339Sdim CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>)); 314221339Sdim } 315221339Sdim}; 316221339Sdim 317221339Sdimclass DeadSymbols { 318221339Sdim template <typename CHECKER> 319221339Sdim static void _checkDeadSymbols(void *checker, 320221339Sdim SymbolReaper &SR, CheckerContext &C) { 321221339Sdim ((const CHECKER *)checker)->checkDeadSymbols(SR, C); 322221339Sdim } 323221339Sdim 324221339Sdimpublic: 325221339Sdim template <typename CHECKER> 326221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 327221339Sdim mgr._registerForDeadSymbols( 328221339Sdim CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>)); 329221339Sdim } 330221339Sdim}; 331221339Sdim 332221339Sdimclass RegionChanges { 333221339Sdim template <typename CHECKER> 334341825Sdim static ProgramStateRef 335226633Sdim _checkRegionChanges(void *checker, 336234353Sdim ProgramStateRef state, 337249423Sdim const InvalidatedSymbols *invalidated, 338226633Sdim ArrayRef<const MemRegion *> Explicits, 339234353Sdim ArrayRef<const MemRegion *> Regions, 340321369Sdim const LocationContext *LCtx, 341239462Sdim const CallEvent *Call) { 342321369Sdim return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated, 343321369Sdim Explicits, Regions, 344321369Sdim LCtx, Call); 345221339Sdim } 346221339Sdim 347221339Sdimpublic: 348221339Sdim template <typename CHECKER> 349221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 350221339Sdim mgr._registerForRegionChanges( 351221339Sdim CheckerManager::CheckRegionChangesFunc(checker, 352314564Sdim _checkRegionChanges<CHECKER>)); 353221339Sdim } 354221339Sdim}; 355221339Sdim 356249423Sdimclass PointerEscape { 357249423Sdim template <typename CHECKER> 358249423Sdim static ProgramStateRef 359261991Sdim _checkPointerEscape(void *Checker, 360249423Sdim ProgramStateRef State, 361249423Sdim const InvalidatedSymbols &Escaped, 362249423Sdim const CallEvent *Call, 363249423Sdim PointerEscapeKind Kind, 364261991Sdim RegionAndSymbolInvalidationTraits *ETraits) { 365261991Sdim 366261991Sdim if (!ETraits) 367261991Sdim return ((const CHECKER *)Checker)->checkPointerEscape(State, 368249423Sdim Escaped, 369249423Sdim Call, 370249423Sdim Kind); 371261991Sdim 372261991Sdim InvalidatedSymbols RegularEscape; 373341825Sdim for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 374261991Sdim E = Escaped.end(); I != E; ++I) 375261991Sdim if (!ETraits->hasTrait(*I, 376261991Sdim RegionAndSymbolInvalidationTraits::TK_PreserveContents) && 377261991Sdim !ETraits->hasTrait(*I, 378261991Sdim RegionAndSymbolInvalidationTraits::TK_SuppressEscape)) 379261991Sdim RegularEscape.insert(*I); 380261991Sdim 381261991Sdim if (RegularEscape.empty()) 382261991Sdim return State; 383261991Sdim 384261991Sdim return ((const CHECKER *)Checker)->checkPointerEscape(State, 385261991Sdim RegularEscape, 386261991Sdim Call, 387261991Sdim Kind); 388249423Sdim } 389249423Sdim 390249423Sdimpublic: 391249423Sdim template <typename CHECKER> 392249423Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 393249423Sdim mgr._registerForPointerEscape( 394249423Sdim CheckerManager::CheckPointerEscapeFunc(checker, 395249423Sdim _checkPointerEscape<CHECKER>)); 396249423Sdim } 397249423Sdim}; 398249423Sdim 399249423Sdimclass ConstPointerEscape { 400249423Sdim template <typename CHECKER> 401249423Sdim static ProgramStateRef 402261991Sdim _checkConstPointerEscape(void *Checker, 403249423Sdim ProgramStateRef State, 404249423Sdim const InvalidatedSymbols &Escaped, 405249423Sdim const CallEvent *Call, 406249423Sdim PointerEscapeKind Kind, 407261991Sdim RegionAndSymbolInvalidationTraits *ETraits) { 408261991Sdim 409261991Sdim if (!ETraits) 410261991Sdim return State; 411261991Sdim 412261991Sdim InvalidatedSymbols ConstEscape; 413341825Sdim for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 414261991Sdim E = Escaped.end(); I != E; ++I) 415261991Sdim if (ETraits->hasTrait(*I, 416261991Sdim RegionAndSymbolInvalidationTraits::TK_PreserveContents) && 417261991Sdim !ETraits->hasTrait(*I, 418261991Sdim RegionAndSymbolInvalidationTraits::TK_SuppressEscape)) 419261991Sdim ConstEscape.insert(*I); 420261991Sdim 421261991Sdim if (ConstEscape.empty()) 422261991Sdim return State; 423261991Sdim 424261991Sdim return ((const CHECKER *)Checker)->checkConstPointerEscape(State, 425261991Sdim ConstEscape, 426261991Sdim Call, 427261991Sdim Kind); 428249423Sdim } 429249423Sdim 430249423Sdimpublic: 431249423Sdim template <typename CHECKER> 432249423Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 433249423Sdim mgr._registerForPointerEscape( 434249423Sdim CheckerManager::CheckPointerEscapeFunc(checker, 435249423Sdim _checkConstPointerEscape<CHECKER>)); 436249423Sdim } 437249423Sdim}; 438249423Sdim 439341825Sdim 440221339Sdimtemplate <typename EVENT> 441221339Sdimclass Event { 442221339Sdim template <typename CHECKER> 443221339Sdim static void _checkEvent(void *checker, const void *event) { 444221339Sdim ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event); 445221339Sdim } 446221339Sdimpublic: 447221339Sdim template <typename CHECKER> 448221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 449221339Sdim mgr._registerListenerForEvent<EVENT>( 450221339Sdim CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>)); 451221339Sdim } 452221339Sdim}; 453221339Sdim 454221339Sdim} // end check namespace 455221339Sdim 456221339Sdimnamespace eval { 457221339Sdim 458221339Sdimclass Assume { 459221339Sdim template <typename CHECKER> 460234353Sdim static ProgramStateRef _evalAssume(void *checker, 461234353Sdim ProgramStateRef state, 462226633Sdim const SVal &cond, 463226633Sdim bool assumption) { 464221339Sdim return ((const CHECKER *)checker)->evalAssume(state, cond, assumption); 465221339Sdim } 466221339Sdim 467221339Sdimpublic: 468221339Sdim template <typename CHECKER> 469221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 470221339Sdim mgr._registerForEvalAssume( 471221339Sdim CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>)); 472221339Sdim } 473221339Sdim}; 474221339Sdim 475221339Sdimclass Call { 476221339Sdim template <typename CHECKER> 477353358Sdim static bool _evalCall(void *checker, const CallEvent &Call, 478353358Sdim CheckerContext &C) { 479353358Sdim return ((const CHECKER *)checker)->evalCall(Call, C); 480221339Sdim } 481221339Sdim 482221339Sdimpublic: 483221339Sdim template <typename CHECKER> 484221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 485221339Sdim mgr._registerForEvalCall( 486221339Sdim CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>)); 487221339Sdim } 488221339Sdim}; 489221339Sdim 490221339Sdim} // end eval namespace 491221339Sdim 492226633Sdimclass CheckerBase : public ProgramPointTag { 493360784Sdim CheckerNameRef Name; 494276479Sdim friend class ::clang::ento::CheckerManager; 495276479Sdim 496226633Sdimpublic: 497276479Sdim StringRef getTagDescription() const override; 498360784Sdim CheckerNameRef getCheckerName() const; 499226633Sdim 500226633Sdim /// See CheckerManager::runCheckersForPrintState. 501234353Sdim virtual void printState(raw_ostream &Out, ProgramStateRef State, 502226633Sdim const char *NL, const char *Sep) const { } 503226633Sdim}; 504276479Sdim 505276479Sdim/// Dump checker name to stream. 506276479Sdimraw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker); 507276479Sdim 508341825Sdim/// Tag that can use a checker name as a message provider 509276479Sdim/// (see SimpleProgramPointTag). 510276479Sdimclass CheckerProgramPointTag : public SimpleProgramPointTag { 511276479Sdimpublic: 512276479Sdim CheckerProgramPointTag(StringRef CheckerName, StringRef Msg); 513276479Sdim CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg); 514276479Sdim}; 515276479Sdim 516288943Sdimtemplate <typename CHECK1, typename... CHECKs> 517288943Sdimclass Checker : public CHECK1, public CHECKs..., public CheckerBase { 518221339Sdimpublic: 519288943Sdim template <typename CHECKER> 520288943Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 521288943Sdim CHECK1::_register(checker, mgr); 522288943Sdim Checker<CHECKs...>::_register(checker, mgr); 523288943Sdim } 524221339Sdim}; 525221339Sdim 526288943Sdimtemplate <typename CHECK1> 527288943Sdimclass Checker<CHECK1> : public CHECK1, public CheckerBase { 528221339Sdimpublic: 529221339Sdim template <typename CHECKER> 530221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 531221339Sdim CHECK1::_register(checker, mgr); 532221339Sdim } 533221339Sdim}; 534221339Sdim 535221339Sdimtemplate <typename EVENT> 536221339Sdimclass EventDispatcher { 537221339Sdim CheckerManager *Mgr; 538221339Sdimpublic: 539276479Sdim EventDispatcher() : Mgr(nullptr) { } 540221339Sdim 541221339Sdim template <typename CHECKER> 542221339Sdim static void _register(CHECKER *checker, CheckerManager &mgr) { 543221339Sdim mgr._registerDispatcherForEvent<EVENT>(); 544221339Sdim static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr; 545221339Sdim } 546221339Sdim 547221339Sdim void dispatchEvent(const EVENT &event) const { 548221339Sdim Mgr->_dispatchEvent(event); 549221339Sdim } 550221339Sdim}; 551221339Sdim 552341825Sdim/// We dereferenced a location that may be null. 553221339Sdimstruct ImplicitNullDerefEvent { 554221339Sdim SVal Location; 555221339Sdim bool IsLoad; 556221339Sdim ExplodedNode *SinkNode; 557221339Sdim BugReporter *BR; 558296417Sdim // When true, the dereference is in the source code directly. When false, the 559296417Sdim // dereference might happen later (for example pointer passed to a parameter 560296417Sdim // that is marked with nonnull attribute.) 561296417Sdim bool IsDirectDereference; 562344779Sdim 563344779Sdim static int Tag; 564221339Sdim}; 565221339Sdim 566341825Sdim/// A helper class which wraps a boolean value set to false by default. 567261991Sdim/// 568261991Sdim/// This class should behave exactly like 'bool' except that it doesn't need to 569261991Sdim/// be explicitly initialized. 570249423Sdimstruct DefaultBool { 571249423Sdim bool val; 572249423Sdim DefaultBool() : val(false) {} 573261991Sdim /*implicit*/ operator bool&() { return val; } 574261991Sdim /*implicit*/ operator const bool&() const { return val; } 575249423Sdim DefaultBool &operator=(bool b) { val = b; return *this; } 576249423Sdim}; 577249423Sdim 578221339Sdim} // end ento namespace 579221339Sdim 580221339Sdim} // end clang namespace 581221339Sdim 582221339Sdim#endif 583