1ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
29fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//
39fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
49fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//
59fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
69fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
79fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//
89fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
99fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//
10ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis//  This file defines Checker, used to create and register checkers.
119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//
129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
14ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_CHECKER
15ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_CHECKER
169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
17ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "clang/Analysis/ProgramPoint.h"
189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
19b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/Support/Casting.h"
219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace clang {
239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace ento {
249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class BugReporter;
259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace check {
279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisstruct _VoidCheck {
299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(void *checker, CheckerManager &mgr) { }
309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidistemplate <typename DECL>
339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisclass ASTDecl {
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                         BugReporter &BR) {
37cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static bool _handlesDecl(const Decl *D) {
41cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    return isa<DECL>(D);
429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic:
449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
46769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
47769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                       _checkDecl<CHECKER>),
48769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                         _handlesDecl);
499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisclass ASTCodeBody {
539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                         BugReporter &BR) {
569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic:
609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
63769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                       _checkBody<CHECKER>));
64769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
65769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
66769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
679be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekclass EndOfTranslationUnit {
689be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  template <typename CHECKER>
699be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  static void _checkEndOfTranslationUnit(void *checker,
709be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         const TranslationUnitDecl *TU,
719be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager& mgr,
729be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR) {
739be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek    ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
749be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  }
759be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
769be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekpublic:
779be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  template <typename CHECKER>
789be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  static void _register(CHECKER *checker, CheckerManager &mgr){
799be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek    mgr._registerForEndOfTranslationUnit(
809be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                              CheckerManager::CheckEndOfTranslationUnit(checker,
819be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                          _checkEndOfTranslationUnit<CHECKER>));
829be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  }
839be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek};
849be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename STMT>
86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PreStmt {
87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
89cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
92769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static bool _handlesStmt(const Stmt *S) {
93cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    return isa<STMT>(S);
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
95769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
96769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
97769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                          _checkStmt<CHECKER>),
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            _handlesStmt);
101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
102769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename STMT>
105769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PostStmt {
106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
107769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
108cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
110769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static bool _handlesStmt(const Stmt *S) {
112cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    return isa<STMT>(S);
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                           _checkStmt<CHECKER>),
119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             _handlesStmt);
120769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
121769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
122769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PreObjCMessage {
124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
125de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                CheckerContext &C) {
127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
132769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
133769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPreObjCMessage(
134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PostObjCMessage {
139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
140de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                CheckerContext &C) {
142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPostObjCMessage(
149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
15396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Roseclass PreCall {
15496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
15596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _checkCall(void *checker, const CallEvent &msg,
15696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                         CheckerContext &C) {
15796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    ((const CHECKER *)checker)->checkPreCall(msg, C);
15896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
15996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
16096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosepublic:
16196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
16296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _register(CHECKER *checker, CheckerManager &mgr) {
16396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    mgr._registerForPreCall(
16496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
16596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
16696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose};
16796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
16896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Roseclass PostCall {
16996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
17096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _checkCall(void *checker, const CallEvent &msg,
17196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                         CheckerContext &C) {
17296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    ((const CHECKER *)checker)->checkPostCall(msg, C);
17396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
17496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
17596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosepublic:
17696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
17796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _register(CHECKER *checker, CheckerManager &mgr) {
17896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    mgr._registerForPostCall(
17996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
18096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
18196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose};
18296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass Location {
184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
185390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  static void _checkLocation(void *checker,
186390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                             const SVal &location, bool isLoad, const Stmt *S,
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             CheckerContext &C) {
188390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks    ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForLocation(
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis           CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
1969fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
1979fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
1989fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
199312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisclass Bind {
200312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
201390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  static void _checkBind(void *checker,
202390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                         const SVal &location, const SVal &val, const Stmt *S,
203312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                         CheckerContext &C) {
204390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks    ((const CHECKER *)checker)->checkBind(location, val, S, C);
205312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
206312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
207312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidispublic:
208312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
209312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
210312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    mgr._registerForBind(
211312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis           CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
212312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
213312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis};
214312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
21530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisclass EndAnalysis {
21630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  template <typename CHECKER>
21730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
21830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                BugReporter &BR, ExprEngine &Eng) {
21930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
22030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  }
22130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
22230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidispublic:
22330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  template <typename CHECKER>
22430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
22530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    mgr._registerForEndAnalysis(
22630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis     CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
22730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  }
22830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis};
22930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
230344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaksclass EndFunction {
231af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  template <typename CHECKER>
232344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  static void _checkEndFunction(void *checker,
233344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                CheckerContext &C) {
234344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks    ((const CHECKER *)checker)->checkEndFunction(C);
235af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  }
236af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
237af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidispublic:
238af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  template <typename CHECKER>
239af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
240344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks    mgr._registerForEndFunction(
241344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks     CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
242af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  }
243af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis};
244af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
245cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisclass BranchCondition {
246cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  template <typename CHECKER>
247f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  static void _checkBranchCondition(void *checker, const Stmt *Condition,
248f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                                    CheckerContext & C) {
249f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks    ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
250cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  }
251cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
252cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidispublic:
253cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  template <typename CHECKER>
254cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
255cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis    mgr._registerForBranchCondition(
256cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckerManager::CheckBranchConditionFunc(checker,
257cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                               _checkBranchCondition<CHECKER>));
258cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  }
259cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis};
260cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
261183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass LiveSymbols {
262183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
26323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
264183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                SymbolReaper &SR) {
265183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
266183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
267183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
268183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic:
269183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
270183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
271183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    mgr._registerForLiveSymbols(
272183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis     CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
273183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
274183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis};
275183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
276183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass DeadSymbols {
277183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
278183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _checkDeadSymbols(void *checker,
279183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                SymbolReaper &SR, CheckerContext &C) {
280183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
281183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
282183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
283183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic:
284183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
285183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
286183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    mgr._registerForDeadSymbols(
287183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis     CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
288183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
289183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis};
290183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
291183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass RegionChanges {
292183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
29323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  static ProgramStateRef
29418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  _checkRegionChanges(void *checker,
29523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek                      ProgramStateRef state,
296bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                      const InvalidatedSymbols *invalidated,
297537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                      ArrayRef<const MemRegion *> Explicits,
29866c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                      ArrayRef<const MemRegion *> Regions,
299740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                      const CallEvent *Call) {
30035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
30166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                                      Explicits, Regions, Call);
302183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
303183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
30418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  static bool _wantsRegionChangeUpdate(void *checker,
30523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek                                       ProgramStateRef state) {
306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
307183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
308183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
309183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic:
310183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    mgr._registerForRegionChanges(
313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis          CheckerManager::CheckRegionChangesFunc(checker,
314183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                                 _checkRegionChanges<CHECKER>),
315183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis          CheckerManager::WantsRegionChangeUpdateFunc(checker,
316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                            _wantsRegionChangeUpdate<CHECKER>));
317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
318183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis};
319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
320bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaksclass PointerEscape {
321bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  template <typename CHECKER>
322bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  static ProgramStateRef
323da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  _checkPointerEscape(void *Checker,
324bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                     ProgramStateRef State,
325bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                     const InvalidatedSymbols &Escaped,
326233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                     const CallEvent *Call,
32741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                     PointerEscapeKind Kind,
328da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                     RegionAndSymbolInvalidationTraits *ETraits) {
329da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
330da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (!ETraits)
331da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return ((const CHECKER *)Checker)->checkPointerEscape(State,
33241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                                            Escaped,
33341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                                            Call,
33441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                                            Kind);
335da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
336da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    InvalidatedSymbols RegularEscape;
337da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
338da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                            E = Escaped.end(); I != E; ++I)
339da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      if (!ETraits->hasTrait(*I,
340b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
341b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev          !ETraits->hasTrait(*I,
342b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
343da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev        RegularEscape.insert(*I);
344da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
345da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (RegularEscape.empty())
346da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return State;
347da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
348da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    return ((const CHECKER *)Checker)->checkPointerEscape(State,
349da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                          RegularEscape,
350da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                          Call,
351da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                          Kind);
352bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  }
353bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
354bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zakspublic:
355bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  template <typename CHECKER>
356bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  static void _register(CHECKER *checker, CheckerManager &mgr) {
357bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks    mgr._registerForPointerEscape(
358bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks          CheckerManager::CheckPointerEscapeFunc(checker,
359bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                                                _checkPointerEscape<CHECKER>));
360bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  }
361bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks};
362bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
36341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksclass ConstPointerEscape {
36441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  template <typename CHECKER>
36541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  static ProgramStateRef
366da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  _checkConstPointerEscape(void *Checker,
36741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      ProgramStateRef State,
36841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      const InvalidatedSymbols &Escaped,
36941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      const CallEvent *Call,
37041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      PointerEscapeKind Kind,
371da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                      RegionAndSymbolInvalidationTraits *ETraits) {
372da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
373da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (!ETraits)
374da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return State;
375da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
376da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    InvalidatedSymbols ConstEscape;
377da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
378da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                            E = Escaped.end(); I != E; ++I)
379da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      if (ETraits->hasTrait(*I,
380b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
381b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev          !ETraits->hasTrait(*I,
382b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
383da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev        ConstEscape.insert(*I);
384da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
385da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (ConstEscape.empty())
386da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return State;
387da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
388da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
389da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                               ConstEscape,
390da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                               Call,
391da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                               Kind);
39241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  }
39341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
39441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zakspublic:
39541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  template <typename CHECKER>
39641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  static void _register(CHECKER *checker, CheckerManager &mgr) {
39741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks    mgr._registerForPointerEscape(
39841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks      CheckerManager::CheckPointerEscapeFunc(checker,
39941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                            _checkConstPointerEscape<CHECKER>));
40041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  }
40141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks};
40241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
40341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
404deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename EVENT>
405deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisclass Event {
406deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename CHECKER>
407deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _checkEvent(void *checker, const void *event) {
408deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
409deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
410deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic:
411deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename CHECKER>
412deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
413deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    mgr._registerListenerForEvent<EVENT>(
414deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis                 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
415deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
416deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis};
417deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
4189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end check namespace
4199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
420e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisnamespace eval {
421e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
422312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisclass Assume {
423312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
42423111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  static ProgramStateRef _evalAssume(void *checker,
42523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek                                         ProgramStateRef state,
42618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                         const SVal &cond,
42718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                         bool assumption) {
428312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
429312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
430312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
431312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidispublic:
432312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
433312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
434312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    mgr._registerForEvalAssume(
435312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
436312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
437312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis};
438312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
439e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass Call {
440e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  template <typename CHECKER>
441e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
442e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    return ((const CHECKER *)checker)->evalCall(CE, C);
443e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
444e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
445e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic:
446e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  template <typename CHECKER>
447e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
448e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    mgr._registerForEvalCall(
449e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                     CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
450e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
451e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis};
452e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
453e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} // end eval namespace
454e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
455ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass CheckerBase : public ProgramPointTag {
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName Name;
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  friend class ::clang::ento::CheckerManager;
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
459ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic:
460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef getTagDescription() const override;
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName getCheckName() const;
462dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
463dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// See CheckerManager::runCheckersForPrintState.
46423111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  virtual void printState(raw_ostream &Out, ProgramStateRef State,
465dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                          const char *NL, const char *Sep) const { }
466ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek};
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Dump checker name to stream.
469651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesraw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Tag that can use a checker name as a message provider
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// (see SimpleProgramPointTag).
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass CheckerProgramPointTag : public SimpleProgramPointTag {
474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidistemplate <typename CHECK1, typename CHECK2=check::_VoidCheck,
4809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis          typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
4819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis          typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
4829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis          typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
4839fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis          typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
484321d70fbde6a0d584a05845f605744889193e70bJordy Rose          typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck,
485321d70fbde6a0d584a05845f605744889193e70bJordy Rose          typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck,
486d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks          typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck,
48796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose          typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck,
48896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose          typename CHECK19=check::_VoidCheck,typename CHECK20=check::_VoidCheck,
48996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose          typename CHECK21=check::_VoidCheck,typename CHECK22=check::_VoidCheck,
49096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose          typename CHECK23=check::_VoidCheck,typename CHECK24=check::_VoidCheck>
491ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass Checker;
492deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
493deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <>
49496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Roseclass Checker<check::_VoidCheck>
495ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  : public CheckerBase
496ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek{
49799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
498deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic:
499deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _register(void *checker, CheckerManager &mgr) { }
500deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis};
501deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
502deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
503deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis          typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
504321d70fbde6a0d584a05845f605744889193e70bJordy Rose          typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12,
505d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks          typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16,
50696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose          typename CHECK17,typename CHECK18,typename CHECK19,typename CHECK20,
50796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose          typename CHECK21,typename CHECK22,typename CHECK23,typename CHECK24>
508ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass Checker
509deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    : public CHECK1,
51096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose      public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
51196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                     CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
51296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                     CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
51396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                     CHECK20,CHECK21,CHECK22,CHECK23,CHECK24> {
5149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic:
5159fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
5169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
5179fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECK1::_register(checker, mgr);
51896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
51996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose            CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
52096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose            CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
52196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose            CHECK20,CHECK21,CHECK22,CHECK23,CHECK24>::_register(checker, mgr);
522deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
523deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis};
524deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
525deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename EVENT>
526deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisclass EventDispatcher {
527deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  CheckerManager *Mgr;
528deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic:
5296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EventDispatcher() : Mgr(nullptr) { }
530deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
531deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename CHECKER>
532deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
533deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    mgr._registerDispatcherForEvent<EVENT>();
534deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
535deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
536deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
537deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void dispatchEvent(const EVENT &event) const {
538deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    Mgr->_dispatchEvent(event);
5399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
5409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
5419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
542b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis/// \brief We dereferenced a location that may be null.
543b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidisstruct ImplicitNullDerefEvent {
544b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  SVal Location;
545b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  bool IsLoad;
546b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  ExplodedNode *SinkNode;
547b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  BugReporter *BR;
548b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis};
549b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis
550adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks/// \brief A helper class which wraps a boolean value set to false by default.
551cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose///
552cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose/// This class should behave exactly like 'bool' except that it doesn't need to
553cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose/// be explicitly initialized.
554adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaksstruct DefaultBool {
555adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks  bool val;
556adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks  DefaultBool() : val(false) {}
557cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose  /*implicit*/ operator bool&() { return val; }
558cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose  /*implicit*/ operator const bool&() const { return val; }
559adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks  DefaultBool &operator=(bool b) { val = b; return *this; }
560adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks};
561adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks
5629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end ento namespace
5639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
5649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end clang namespace
5659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
5669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#endif
567