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
14176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
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 Kyrtzidistemplate <typename DECL>
299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisclass ASTDecl {
309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                         BugReporter &BR) {
33cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static bool _handlesDecl(const Decl *D) {
37cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    return isa<DECL>(D);
389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic:
409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
42769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
43769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                       _checkDecl<CHECKER>),
44769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                         _handlesDecl);
459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisclass ASTCodeBody {
499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                         BugReporter &BR) {
529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic:
569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
58769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
59769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                       _checkBody<CHECKER>));
60769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
61769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
639be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekclass EndOfTranslationUnit {
649be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  template <typename CHECKER>
659be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  static void _checkEndOfTranslationUnit(void *checker,
669be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         const TranslationUnitDecl *TU,
679be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager& mgr,
689be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR) {
699be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek    ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
709be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  }
719be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
729be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekpublic:
739be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  template <typename CHECKER>
749be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  static void _register(CHECKER *checker, CheckerManager &mgr){
759be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek    mgr._registerForEndOfTranslationUnit(
769be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                              CheckerManager::CheckEndOfTranslationUnit(checker,
779be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                          _checkEndOfTranslationUnit<CHECKER>));
789be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  }
799be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek};
809be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename STMT>
82769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PreStmt {
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
85cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static bool _handlesStmt(const Stmt *S) {
89cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    return isa<STMT>(S);
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
92769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
95769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                          _checkStmt<CHECKER>),
96769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            _handlesStmt);
97769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename STMT>
101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PostStmt {
102769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
104cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
105769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
107769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static bool _handlesStmt(const Stmt *S) {
108cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    return isa<STMT>(S);
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
110769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
112769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                                           _checkStmt<CHECKER>),
115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             _handlesStmt);
116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PreObjCMessage {
120769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
121de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
122769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                CheckerContext &C) {
123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
125769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPreObjCMessage(
130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
132769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
133769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
13487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass ObjCMessageNil {
13587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  template <typename CHECKER>
13687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
13787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                CheckerContext &C) {
13887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ((const CHECKER *)checker)->checkObjCMessageNil(msg, C);
13987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
14087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
14187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarpublic:
14287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  template <typename CHECKER>
14387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  static void _register(CHECKER *checker, CheckerManager &mgr) {
14487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    mgr._registerForObjCMessageNil(
14587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
14687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
14787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
14887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PostObjCMessage {
150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
151de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                CheckerContext &C) {
153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
155769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForPostObjCMessage(
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
16496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Roseclass PreCall {
16596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
16696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _checkCall(void *checker, const CallEvent &msg,
16796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                         CheckerContext &C) {
16896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    ((const CHECKER *)checker)->checkPreCall(msg, C);
16996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
17096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
17196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosepublic:
17296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
17396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _register(CHECKER *checker, CheckerManager &mgr) {
17496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    mgr._registerForPreCall(
17596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
17696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
17796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose};
17896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
17996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Roseclass PostCall {
18096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
18196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _checkCall(void *checker, const CallEvent &msg,
18296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                         CheckerContext &C) {
18396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    ((const CHECKER *)checker)->checkPostCall(msg, C);
18496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
18596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
18696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosepublic:
18796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  template <typename CHECKER>
18896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  static void _register(CHECKER *checker, CheckerManager &mgr) {
18996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    mgr._registerForPostCall(
19096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
19196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
19296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose};
19396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass Location {
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
196390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  static void _checkLocation(void *checker,
197390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                             const SVal &location, bool isLoad, const Stmt *S,
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             CheckerContext &C) {
199390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks    ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <typename CHECKER>
204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    mgr._registerForLocation(
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis           CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
2079fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
2089fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
2099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
210312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisclass Bind {
211312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
212390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  static void _checkBind(void *checker,
213390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                         const SVal &location, const SVal &val, const Stmt *S,
214312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                         CheckerContext &C) {
215390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks    ((const CHECKER *)checker)->checkBind(location, val, S, C);
216312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
217312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
218312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidispublic:
219312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
220312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
221312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    mgr._registerForBind(
222312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis           CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
223312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
224312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis};
225312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
22630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisclass EndAnalysis {
22730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  template <typename CHECKER>
22830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
22930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                BugReporter &BR, ExprEngine &Eng) {
23030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
23130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  }
23230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
23330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidispublic:
23430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  template <typename CHECKER>
23530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
23630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    mgr._registerForEndAnalysis(
23730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis     CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
23830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  }
23930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis};
24030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
2414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass BeginFunction {
2424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  template <typename CHECKER>
2434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static void _checkBeginFunction(void *checker, CheckerContext &C) {
2444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ((const CHECKER *)checker)->checkBeginFunction(C);
2454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
2484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  template <typename CHECKER>
2494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static void _register(CHECKER *checker, CheckerManager &mgr) {
2504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    mgr._registerForBeginFunction(CheckerManager::CheckBeginFunctionFunc(
2514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        checker, _checkBeginFunction<CHECKER>));
2524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
2544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
255344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaksclass EndFunction {
256af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  template <typename CHECKER>
257344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  static void _checkEndFunction(void *checker,
258344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                CheckerContext &C) {
259344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks    ((const CHECKER *)checker)->checkEndFunction(C);
260af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  }
261af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
262af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidispublic:
263af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  template <typename CHECKER>
264af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
265344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks    mgr._registerForEndFunction(
266344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks     CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
267af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  }
268af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis};
269af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
270cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisclass BranchCondition {
271cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  template <typename CHECKER>
272f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  static void _checkBranchCondition(void *checker, const Stmt *Condition,
273f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                                    CheckerContext & C) {
274f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks    ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
275cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  }
276cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
277cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidispublic:
278cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  template <typename CHECKER>
279cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
280cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis    mgr._registerForBranchCondition(
281cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckerManager::CheckBranchConditionFunc(checker,
282cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                               _checkBranchCondition<CHECKER>));
283cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  }
284cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis};
285cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
286183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass LiveSymbols {
287183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
28823111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
289183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                SymbolReaper &SR) {
290183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
291183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
292183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
293183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic:
294183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
295183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
296183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    mgr._registerForLiveSymbols(
297183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis     CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
298183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
299183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis};
300183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
301183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass DeadSymbols {
302183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
303183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _checkDeadSymbols(void *checker,
304183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                SymbolReaper &SR, CheckerContext &C) {
305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
307183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
308183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic:
309183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
310183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    mgr._registerForDeadSymbols(
312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis     CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
314183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis};
315183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass RegionChanges {
317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
31823111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  static ProgramStateRef
31918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  _checkRegionChanges(void *checker,
32023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek                      ProgramStateRef state,
321bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                      const InvalidatedSymbols *invalidated,
322537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                      ArrayRef<const MemRegion *> Explicits,
32366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                      ArrayRef<const MemRegion *> Regions,
324740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                      const CallEvent *Call) {
32535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
32666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                                      Explicits, Regions, Call);
327183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
328183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
32918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  static bool _wantsRegionChangeUpdate(void *checker,
33023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek                                       ProgramStateRef state) {
331183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
332183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
333183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
334183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic:
335183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  template <typename CHECKER>
336183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
337183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    mgr._registerForRegionChanges(
338183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis          CheckerManager::CheckRegionChangesFunc(checker,
339183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                                 _checkRegionChanges<CHECKER>),
340183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis          CheckerManager::WantsRegionChangeUpdateFunc(checker,
341183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                            _wantsRegionChangeUpdate<CHECKER>));
342183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
343183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis};
344183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
345bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaksclass PointerEscape {
346bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  template <typename CHECKER>
347bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  static ProgramStateRef
348da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  _checkPointerEscape(void *Checker,
349bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                     ProgramStateRef State,
350bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                     const InvalidatedSymbols &Escaped,
351233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                     const CallEvent *Call,
35241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                     PointerEscapeKind Kind,
353da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                     RegionAndSymbolInvalidationTraits *ETraits) {
354da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
355da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (!ETraits)
356da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return ((const CHECKER *)Checker)->checkPointerEscape(State,
35741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                                            Escaped,
35841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                                            Call,
35941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                                            Kind);
360da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
361da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    InvalidatedSymbols RegularEscape;
362da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
363da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                            E = Escaped.end(); I != E; ++I)
364da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      if (!ETraits->hasTrait(*I,
365b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
366b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev          !ETraits->hasTrait(*I,
367b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
368da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev        RegularEscape.insert(*I);
369da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
370da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (RegularEscape.empty())
371da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return State;
372da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
373da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    return ((const CHECKER *)Checker)->checkPointerEscape(State,
374da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                          RegularEscape,
375da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                          Call,
376da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                          Kind);
377bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  }
378bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
379bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zakspublic:
380bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  template <typename CHECKER>
381bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  static void _register(CHECKER *checker, CheckerManager &mgr) {
382bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks    mgr._registerForPointerEscape(
383bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks          CheckerManager::CheckPointerEscapeFunc(checker,
384bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                                                _checkPointerEscape<CHECKER>));
385bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  }
386bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks};
387bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
38841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksclass ConstPointerEscape {
38941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  template <typename CHECKER>
39041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  static ProgramStateRef
391da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  _checkConstPointerEscape(void *Checker,
39241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      ProgramStateRef State,
39341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      const InvalidatedSymbols &Escaped,
39441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      const CallEvent *Call,
39541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                      PointerEscapeKind Kind,
396da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                      RegionAndSymbolInvalidationTraits *ETraits) {
397da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
398da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (!ETraits)
399da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return State;
400da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
401da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    InvalidatedSymbols ConstEscape;
402da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
403da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                            E = Escaped.end(); I != E; ++I)
404da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      if (ETraits->hasTrait(*I,
405b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
406b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev          !ETraits->hasTrait(*I,
407b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
408da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev        ConstEscape.insert(*I);
409da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
410da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    if (ConstEscape.empty())
411da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev      return State;
412da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev
413da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev    return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
414da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                               ConstEscape,
415da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                               Call,
416da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                                               Kind);
41741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  }
41841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
41941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zakspublic:
42041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  template <typename CHECKER>
42141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  static void _register(CHECKER *checker, CheckerManager &mgr) {
42241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks    mgr._registerForPointerEscape(
42341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks      CheckerManager::CheckPointerEscapeFunc(checker,
42441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                            _checkConstPointerEscape<CHECKER>));
42541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  }
42641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks};
42741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
42841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
429deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename EVENT>
430deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisclass Event {
431deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename CHECKER>
432deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _checkEvent(void *checker, const void *event) {
433deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
434deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
435deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic:
436deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename CHECKER>
437deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
438deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    mgr._registerListenerForEvent<EVENT>(
439deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis                 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
440deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
441deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis};
442deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
4439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end check namespace
4449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
445e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisnamespace eval {
446e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
447312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisclass Assume {
448312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
44923111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  static ProgramStateRef _evalAssume(void *checker,
45023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek                                         ProgramStateRef state,
45118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                         const SVal &cond,
45218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                         bool assumption) {
453312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
454312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
455312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
456312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidispublic:
457312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  template <typename CHECKER>
458312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
459312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    mgr._registerForEvalAssume(
460312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
461312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
462312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis};
463312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
464e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass Call {
465e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  template <typename CHECKER>
466e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
467e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    return ((const CHECKER *)checker)->evalCall(CE, C);
468e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
469e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
470e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic:
471e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  template <typename CHECKER>
472e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
473e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    mgr._registerForEvalCall(
474e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                     CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
475e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
476e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis};
477e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
478e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} // end eval namespace
479e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
480ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekclass CheckerBase : public ProgramPointTag {
481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName Name;
482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  friend class ::clang::ento::CheckerManager;
483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
484ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekpublic:
485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef getTagDescription() const override;
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName getCheckName() const;
487dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
488dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// See CheckerManager::runCheckersForPrintState.
48923111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  virtual void printState(raw_ostream &Out, ProgramStateRef State,
490dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                          const char *NL, const char *Sep) const { }
491ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek};
492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Dump checker name to stream.
494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesraw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Tag that can use a checker name as a message provider
497651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// (see SimpleProgramPointTag).
498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass CheckerProgramPointTag : public SimpleProgramPointTag {
499651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
503651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
5040e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate <typename CHECK1, typename... CHECKs>
5050e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Checker : public CHECK1, public CHECKs..., public CheckerBase {
506deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic:
5070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  template <typename CHECKER>
5080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  static void _register(CHECKER *checker, CheckerManager &mgr) {
5090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    CHECK1::_register(checker, mgr);
5100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Checker<CHECKs...>::_register(checker, mgr);
5110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
512deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis};
513deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
5140e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate <typename CHECK1>
5150e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Checker<CHECK1> : public CHECK1, public CheckerBase {
5169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic:
5179fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
5189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
5199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECK1::_register(checker, mgr);
520deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
521deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis};
522deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
523deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename EVENT>
524deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisclass EventDispatcher {
525deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  CheckerManager *Mgr;
526deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic:
5276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EventDispatcher() : Mgr(nullptr) { }
528deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
529deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename CHECKER>
530deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void _register(CHECKER *checker, CheckerManager &mgr) {
531deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    mgr._registerDispatcherForEvent<EVENT>();
532deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
533deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
534deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
535deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void dispatchEvent(const EVENT &event) const {
536deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    Mgr->_dispatchEvent(event);
5379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
5389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis};
5399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
540b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis/// \brief We dereferenced a location that may be null.
541b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidisstruct ImplicitNullDerefEvent {
542b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  SVal Location;
543b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  bool IsLoad;
544b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  ExplodedNode *SinkNode;
545b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis  BugReporter *BR;
54687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // When true, the dereference is in the source code directly. When false, the
54787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // dereference might happen later (for example pointer passed to a parameter
54887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // that is marked with nonnull attribute.)
54987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  bool IsDirectDereference;
550b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis};
551b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis
552adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks/// \brief A helper class which wraps a boolean value set to false by default.
553cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose///
554cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose/// This class should behave exactly like 'bool' except that it doesn't need to
555cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose/// be explicitly initialized.
556adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaksstruct DefaultBool {
557adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks  bool val;
558adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks  DefaultBool() : val(false) {}
559cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose  /*implicit*/ operator bool&() { return val; }
560cce70c7c5f0f4c1a41658fbed845f8b3a565c99cJordan Rose  /*implicit*/ operator const bool&() const { return val; }
561adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks  DefaultBool &operator=(bool b) { val = b; return *this; }
562adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks};
563adecec39481f925701e63d7fe3b8bf02dd7ddf01Anna Zaks
5649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end ento namespace
5659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
5669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end clang namespace
5679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
5689fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#endif
569