CheckerManager.h revision deb6447d0029bdb122397fafb5fa2a4e76f2e555
143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===// 243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// 343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// The LLVM Compiler Infrastructure 443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// 543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// License. See LICENSE.TXT for details. 743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// 843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// 1043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Defines the Static Analyzer Checker Manager. 1143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// 1243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===// 1343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 1443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 1543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 1643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h" 1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "llvm/ADT/SmallVector.h" 199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/ADT/DenseMap.h" 20769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "llvm/ADT/FoldingSet.h" 219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include <vector> 2243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace clang { 249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class Decl; 25769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class Stmt; 26e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis class CallExpr; 2743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 2843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace ento { 2943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis class ExprEngine; 309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class AnalysisManager; 319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class BugReporter; 32769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class CheckerContext; 33769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class ObjCMessage; 34769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class SVal; 35e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis class ExplodedNode; 36769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class ExplodedNodeSet; 3730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis class ExplodedGraph; 38769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class GRState; 39af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis class EndOfFunctionNodeBuilder; 40cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis class BranchNodeBuilder; 41183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis class MemRegion; 42183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis class SymbolReaper; 43769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 44e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass GraphExpander { 45e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic: 46e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis virtual ~GraphExpander(); 47e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0; 48e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}; 49e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 50769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisstruct VoidCheckerFnParm {}; 51769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename P1=VoidCheckerFnParm, typename P2=VoidCheckerFnParm, 52769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typename P3=VoidCheckerFnParm, typename P4=VoidCheckerFnParm> 53769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn { 54769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef void (*Func)(void *, P1, P2, P3, P4); 55769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 56769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 57769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 58769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 59769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void operator()(P1 p1, P2 p2, P3 p3, P4 p4) { Fn(Checker, p1, p2, p3, p4); } 60769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 61769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename P1, typename P2, typename P3> 63769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn<P1, P2, P3, VoidCheckerFnParm> { 64769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef void (*Func)(void *, P1, P2, P3); 65769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 66769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 67769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 69769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void operator()(P1 p1, P2 p2, P3 p3) { Fn(Checker, p1, p2, p3); } 70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 72769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename P1, typename P2> 73769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn<P1, P2, VoidCheckerFnParm, VoidCheckerFnParm> { 74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef void (*Func)(void *, P1, P2); 75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 76769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 77769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void operator()(P1 p1, P2 p2) { Fn(Checker, p1, p2); } 80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 82769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <> 83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn<VoidCheckerFnParm, VoidCheckerFnParm, VoidCheckerFnParm, 84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis VoidCheckerFnParm> { 85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef void (*Func)(void *); 86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void operator()() { Fn(Checker); } 91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 9243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 9343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager { 942e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis const LangOptions LangOpts; 952e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis 9643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic: 972e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 989fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis ~CheckerManager(); 999fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 100deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void finishedCheckerRegistration(); 101deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 1022e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis const LangOptions &getLangOptions() const { return LangOpts; } 1032e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis 1049fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef void *CheckerRef; 1053fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis typedef void *CheckerTag; 106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef CheckerFn<> CheckerDtor; 1079fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1089fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker 1109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Used to register checkers. 1133fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis /// 1143fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis /// \returns a pointer to the checker object. 1159fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 1163fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis CHECKER *registerChecker() { 117deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CheckerTag tag = getTag<CHECKER>(); 1183fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis CheckerRef &ref = CheckerTags[tag]; 1193fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis if (ref) 1203fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis return static_cast<CHECKER *>(ref); // already registered. 1213fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 1229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECKER *checker = new CHECKER(); 123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 1249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECKER::_register(checker, *this); 1253fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis ref = checker; 1263fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis return checker; 1279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 12843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 1299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing.. 1319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Run checkers handling Decls. 1349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 1359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR); 1369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Run checkers handling Decls containing a Stmt body. 1389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 1399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR); 1409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking. 143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for pre-visiting Stmts. 146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPreStmt(ExplodedNodeSet &Dst, 147cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for post-visiting Stmts. 154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPostStmt(ExplodedNodeSet &Dst, 155cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng); 159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for visiting Stmts. 162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForStmt(bool isPreVisit, 163cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng); 165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for pre-visiting obj-c messages. 167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 168cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 169769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for post-visiting obj-c messages. 175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 176cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng); 180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for visiting obj-c messages. 183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForObjCMessage(bool isPreVisit, 184cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet &Dst, 185cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, ExprEngine &Eng); 187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for load/store of a location. 189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForLocation(ExplodedNodeSet &Dst, 190cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal location, bool isLoad, 192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng); 194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 195312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis /// \brief Run checkers for binding of a value to a location. 196312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void runCheckersForBind(ExplodedNodeSet &Dst, 197312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const ExplodedNodeSet &Src, 198312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal location, SVal val, 199312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng); 200312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 20130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis /// \brief Run checkers for end of analysis. 20230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 20330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis ExprEngine &Eng); 20430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 205af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis /// \brief Run checkers for end of path. 206af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng); 207af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 208cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis /// \brief Run checkers for branch condition. 209cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis void runCheckersForBranchCondition(const Stmt *condition, 210cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchNodeBuilder &B, ExprEngine &Eng); 211cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 212183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for live symbols. 213183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runCheckersForLiveSymbols(const GRState *state, 214183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper); 215183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 216183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for dead symbols. 217183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 218183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const ExplodedNodeSet &Src, 219183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper, const Stmt *S, 220183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng); 221183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 222183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief True if at least one checker wants to check region changes. 223183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis bool wantsRegionChangeUpdate(const GRState *state); 224183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 225183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for region changes. 226183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const GRState *runCheckersForRegionChanges(const GRState *state, 227183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *Begin, 228183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *End); 229183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 230312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis /// \brief Run checkers for handling assumptions on symbolic values. 231312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const GRState *runCheckersForEvalAssume(const GRState *state, 232312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Cond, bool Assumption); 233312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 234e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis /// \brief Run checkers for evaluating a call. 235e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void runCheckersForEvalCall(ExplodedNodeSet &Dst, 236e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const ExplodedNodeSet &Src, 237e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const CallExpr *CE, ExprEngine &Eng, 238e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GraphExpander *defaultEval = 0); 239e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 240769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 241769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing. 2429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 2439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 2449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Functions used by the registration mechanism, checkers should not touch 2459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // these directly. 2469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 247769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef CheckerFn<const Decl *, AnalysisManager&, BugReporter &> 248769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckDeclFunc; 249769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 2509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef bool (*HandlesDeclFunc)(const Decl *D); 251769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 2529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 253769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForBody(CheckDeclFunc checkfn); 254769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 255769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 256769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking. 257769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 258769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 259cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc; 260769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc; 261769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &> 262769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckLocationFunc; 263312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis typedef CheckerFn<const SVal &/*location*/, const SVal &/*val*/, 264312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckerContext &> CheckBindFunc; 26530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &> 26630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis CheckEndAnalysisFunc; 267af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis typedef CheckerFn<EndOfFunctionNodeBuilder &, ExprEngine &> CheckEndPathFunc; 268cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis typedef CheckerFn<const Stmt *, BranchNodeBuilder &, ExprEngine &> 269cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckBranchConditionFunc; 270183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis typedef CheckerFn<SymbolReaper &, CheckerContext &> CheckDeadSymbolsFunc; 271183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis typedef CheckerFn<const GRState *, SymbolReaper &> CheckLiveSymbolsFunc; 272769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 273769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef bool (*HandlesStmtFunc)(const Stmt *D); 274769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPreStmt(CheckStmtFunc checkfn, 275769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn); 276769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPostStmt(CheckStmtFunc checkfn, 277769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn); 278769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 279769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 280769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 281769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 282769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForLocation(CheckLocationFunc checkfn); 283769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 284312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void _registerForBind(CheckBindFunc checkfn); 285312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 28630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 28730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 288af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis void _registerForEndPath(CheckEndPathFunc checkfn); 289af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 290cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 291cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 292183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 293183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 294183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 295183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 296183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis class CheckRegionChangesFunc { 297183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis typedef const GRState * (*Func)(void *, const GRState *, 298183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *, 299183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *); 300183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis Func Fn; 301183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis public: 302183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void *Checker; 303183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckRegionChangesFunc(void *checker, Func fn) : Fn(fn), Checker(checker) {} 304183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const GRState *operator()(const GRState *state, 305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *begin, 306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *end) { 307183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return Fn(Checker, state, begin, end); 308183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 309183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 310183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis class WantsRegionChangeUpdateFunc { 312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis typedef bool (*Func)(void *, const GRState *); 313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis Func Fn; 314183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis public: 315183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void *Checker; 316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc(void *checker, Func fn) 317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis : Fn(fn), Checker(checker) { } 318183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis bool operator()(const GRState *state) { 319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return Fn(Checker, state); 320183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 321183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 322183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 323183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 324183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc wantUpdateFn); 325183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 326312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis class EvalAssumeFunc { 327312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis typedef const GRState * (*Func)(void *, const GRState *, 328312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const SVal &/*cond*/, bool /*assumption*/); 329312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis Func Fn; 330312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis public: 331312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void *Checker; 332312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis EvalAssumeFunc(void *checker, Func fn) : Fn(fn), Checker(checker) {} 333312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const GRState *operator()(const GRState *state, 334312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const SVal &cond, bool assumption) { 335312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return Fn(Checker, state, cond, assumption); 336312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 337312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis }; 338312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 339312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void _registerForEvalAssume(EvalAssumeFunc checkfn); 340312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 341e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis class EvalCallFunc { 342e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis typedef bool (*Func)(void *, const CallExpr *, CheckerContext &); 343e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Func Fn; 344e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis public: 345e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void *Checker; 346e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EvalCallFunc(void *checker, Func fn) : Fn(fn), Checker(checker) { } 347e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis bool operator()(const CallExpr *CE, CheckerContext &C) { 348e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis return Fn(Checker, CE, C); 349e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 350e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis }; 351e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 352e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void _registerForEvalCall(EvalCallFunc checkfn); 353e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 354769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 355deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events. 356deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 357deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 358deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef void *EventTag; 359deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 360deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis class CheckEventFunc { 361deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef void (*Func)(void *, const void *); 362deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis Func Fn; 363deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis public: 364deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void *Checker; 365deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CheckEventFunc(void *checker, Func fn) 366deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis : Fn(fn), Checker(checker) { } 367deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void operator()(const void *event) const { 368deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis return Fn(Checker, event); 369deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 370deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis }; 371deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 372deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 373deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _registerListenerForEvent(CheckEventFunc checkfn) { 374deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo &info = Events[getTag<EVENT>()]; 375deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.Checkers.push_back(checkfn); 376deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 377deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 378deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 379deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _registerDispatcherForEvent() { 380deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo &info = Events[getTag<EVENT>()]; 381deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.HasDispatcher = true; 382deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 383deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 384deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 385deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _dispatchEvent(const EVENT &event) const { 386deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 387deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis if (I == Events.end()) 388deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis return; 389deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis const EventInfo &info = I->second; 390deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 391deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.Checkers[i](&event); 392deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 393deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 394deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 395769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details. 396769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 39743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 39843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate: 3999fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 4009fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 4019fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 402deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename T> 403deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void *getTag() { static int tag; return &tag; } 4043fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 4053fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 4063fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 407769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckerDtor> CheckerDtors; 408769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 4099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis struct DeclCheckerInfo { 4109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CheckDeclFunc CheckFn; 4119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis HandlesDeclFunc IsForDeclFn; 4129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis }; 4139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis std::vector<DeclCheckerInfo> DeclCheckers; 4149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 415769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckDeclFunc> BodyCheckers; 4169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 417769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 4189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 4199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckersMapTy CachedDeclCheckersMap; 420769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 421769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct StmtCheckerInfo { 422769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtFunc CheckFn; 423769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc IsForStmtFn; 424769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 425769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 426769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<StmtCheckerInfo> StmtCheckers; 427769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 428769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CachedStmtCheckersKey { 429769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis unsigned StmtKind; 430769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 431769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 432769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 433769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 434769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 435769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 436769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static CachedStmtCheckersKey getSentinel() { 437fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis return CachedStmtCheckersKey(~0U, 0); 438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis unsigned getHashValue() const { 440769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis llvm::FoldingSetNodeID ID; 441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ID.AddInteger(StmtKind); 442769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ID.AddBoolean(IsPreVisit); 443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return ID.ComputeHash(); 444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool operator==(const CachedStmtCheckersKey &RHS) const { 446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 447769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 448769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 449769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 451769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 452769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 453769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy; 454769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy CachedStmtCheckersMap; 455769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 456769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 457769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 458769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 459769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 460769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 461769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckLocationFunc> LocationCheckers; 46230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 463312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<CheckBindFunc> BindCheckers; 464312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 46530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 466e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 467af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis std::vector<CheckEndPathFunc> EndPathCheckers; 468af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 469cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 470cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 471183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 472183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 473183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 474183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 475183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis struct RegionChangesCheckerInfo { 476183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckRegionChangesFunc CheckFn; 477183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc WantUpdateFn; 478183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 479183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 480183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 481312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<EvalAssumeFunc> EvalAssumeCheckers; 482312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 483e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis std::vector<EvalCallFunc> EvalCallCheckers; 484deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 485deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis struct EventInfo { 486deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis llvm::SmallVector<CheckEventFunc, 4> Checkers; 487deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis bool HasDispatcher; 488deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo() : HasDispatcher(false) { } 489deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis }; 490deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 491deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 492deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventsTy Events; 49343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}; 49443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 49543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace 49643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 49743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace 49843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 499769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm { 500769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 501769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// in DenseMap and DenseSets. 502769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <> 503769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 504769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static inline clang::ento::CheckerManager::CachedStmtCheckersKey 505769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getEmptyKey() { 506769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return clang::ento::CheckerManager::CachedStmtCheckersKey(); 507769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 508769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static inline clang::ento::CheckerManager::CachedStmtCheckersKey 509769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getTombstoneKey() { 510769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 511769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 512769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 513769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static unsigned 514769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 515769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return S.getHashValue(); 516769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 517769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 518769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 519769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 520769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return LHS == RHS; 521769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 522769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 523769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm 524769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 52543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif 526