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