CheckerManager.h revision 4d840e9ac4d8e9baa9459ca3dd7ab14ae884a80f
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 504d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn; 514d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 524d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3> 534d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> { 544d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *, P1, P2, P3); 55769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 56769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 57769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 58769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 594d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 60769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 61769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 624d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2> 634d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> { 644d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *, P1, P2); 65769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 66769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 67769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 694d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 724d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1> 734d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> { 744d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *, P1); 75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 76769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 77769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 794d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()(P1 p1) const { return Fn(Checker, p1); } 80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET> 834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> { 844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *); 85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 894d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()() const { return Fn(Checker); } 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 9143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 9243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager { 932e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis const LangOptions LangOpts; 942e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis 9543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic: 962e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 979fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis ~CheckerManager(); 989fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 99d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis bool hasPathSensitiveCheckers() const; 100d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis 101deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void finishedCheckerRegistration(); 102deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 1032e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis const LangOptions &getLangOptions() const { return LangOpts; } 1042e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis 1059fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef void *CheckerRef; 1063fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis typedef void *CheckerTag; 1074d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void ()> CheckerDtor; 1089fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker 1119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Used to register checkers. 1143fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis /// 1153fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis /// \returns a pointer to the checker object. 1169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 1173fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis CHECKER *registerChecker() { 118deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CheckerTag tag = getTag<CHECKER>(); 1193fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis CheckerRef &ref = CheckerTags[tag]; 1203fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis if (ref) 1213fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis return static_cast<CHECKER *>(ref); // already registered. 1223fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 1239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECKER *checker = new CHECKER(); 124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 1259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECKER::_register(checker, *this); 1263fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis ref = checker; 1273fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis return checker; 1289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 12943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 1309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing.. 1329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Run checkers handling Decls. 1359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 1369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR); 1379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Run checkers handling Decls containing a Stmt body. 1399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 1409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR); 1419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking. 144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for pre-visiting Stmts. 147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPreStmt(ExplodedNodeSet &Dst, 148cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for post-visiting Stmts. 155769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPostStmt(ExplodedNodeSet &Dst, 156cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng); 160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for visiting Stmts. 163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForStmt(bool isPreVisit, 164cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng); 166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for pre-visiting obj-c messages. 168769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 169cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for post-visiting obj-c messages. 176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 177cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng); 181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for visiting obj-c messages. 184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForObjCMessage(bool isPreVisit, 185cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet &Dst, 186cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, ExprEngine &Eng); 188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for load/store of a location. 190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForLocation(ExplodedNodeSet &Dst, 191cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal location, bool isLoad, 193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng); 195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 196312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis /// \brief Run checkers for binding of a value to a location. 197312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void runCheckersForBind(ExplodedNodeSet &Dst, 198312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const ExplodedNodeSet &Src, 199312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal location, SVal val, 200312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng); 201312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 20230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis /// \brief Run checkers for end of analysis. 20330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 20430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis ExprEngine &Eng); 20530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 206af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis /// \brief Run checkers for end of path. 207af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng); 208af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 209cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis /// \brief Run checkers for branch condition. 210cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis void runCheckersForBranchCondition(const Stmt *condition, 211cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchNodeBuilder &B, ExprEngine &Eng); 212cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 213183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for live symbols. 214183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runCheckersForLiveSymbols(const GRState *state, 215183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper); 216183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 217183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for dead symbols. 218183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 219183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const ExplodedNodeSet &Src, 220183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper, const Stmt *S, 221183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng); 222183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 223183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief True if at least one checker wants to check region changes. 224183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis bool wantsRegionChangeUpdate(const GRState *state); 225183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 226183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for region changes. 227183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const GRState *runCheckersForRegionChanges(const GRState *state, 228183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *Begin, 229183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *End); 230183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 231312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis /// \brief Run checkers for handling assumptions on symbolic values. 232312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const GRState *runCheckersForEvalAssume(const GRState *state, 233312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Cond, bool Assumption); 234312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 235e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis /// \brief Run checkers for evaluating a call. 236e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void runCheckersForEvalCall(ExplodedNodeSet &Dst, 237e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const ExplodedNodeSet &Src, 238e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const CallExpr *CE, ExprEngine &Eng, 239e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GraphExpander *defaultEval = 0); 240e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 241769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 242769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing. 2439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 2449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 2459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Functions used by the registration mechanism, checkers should not touch 2469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // these directly. 2479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 2484d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)> 249769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckDeclFunc; 250769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 2519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef bool (*HandlesDeclFunc)(const Decl *D); 252769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 2539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 254769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForBody(CheckDeclFunc checkfn); 255769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 256769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 257769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking. 258769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 259769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 2604d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; 2614d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2624d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)> 2634d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckObjCMessageFunc; 2644d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2654d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const SVal &location, bool isLoad, CheckerContext &)> 266769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckLocationFunc; 2674d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2684d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const SVal &location, const SVal &val, 2694d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckerContext &)> CheckBindFunc; 2704d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2714d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> 27230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis CheckEndAnalysisFunc; 2734d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2744d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)> 2754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckEndPathFunc; 2764d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const Stmt *, BranchNodeBuilder &, ExprEngine &)> 278cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckBranchConditionFunc; 2794d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2804d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> 2814d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckDeadSymbolsFunc; 2824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc; 2844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<const GRState * (const GRState *, 2864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis const MemRegion * const *begin, 2874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis const MemRegion * const *end)> 2884d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckRegionChangesFunc; 2894d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2904d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<bool (const GRState *)> WantsRegionChangeUpdateFunc; 2914d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<const GRState * (const GRState *, 2934d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis const SVal &cond, bool assumption)> 2944d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis EvalAssumeFunc; 2954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> 2974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis EvalCallFunc; 298769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 299769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef bool (*HandlesStmtFunc)(const Stmt *D); 300769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPreStmt(CheckStmtFunc checkfn, 301769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn); 302769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPostStmt(CheckStmtFunc checkfn, 303769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn); 304769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 305769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 306769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 307769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 308769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForLocation(CheckLocationFunc checkfn); 309769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 310312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void _registerForBind(CheckBindFunc checkfn); 311312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 31230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 31330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 314af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis void _registerForEndPath(CheckEndPathFunc checkfn); 315af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 316cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 317cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 318183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 320183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 321183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 322183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 323183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc wantUpdateFn); 324183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 325312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void _registerForEvalAssume(EvalAssumeFunc checkfn); 326312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 327e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void _registerForEvalCall(EvalCallFunc checkfn); 328e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 329769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 330deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events. 331deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 332deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 333deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef void *EventTag; 3344d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const void *event)> CheckEventFunc; 335deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 336deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 337deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _registerListenerForEvent(CheckEventFunc checkfn) { 338deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo &info = Events[getTag<EVENT>()]; 339deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.Checkers.push_back(checkfn); 340deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 341deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 342deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 343deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _registerDispatcherForEvent() { 344deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo &info = Events[getTag<EVENT>()]; 345deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.HasDispatcher = true; 346deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 347deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 348deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 349deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _dispatchEvent(const EVENT &event) const { 350deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 351deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis if (I == Events.end()) 352deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis return; 353deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis const EventInfo &info = I->second; 354deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 355deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.Checkers[i](&event); 356deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 357deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 358deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 359769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details. 360769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 36143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 36243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate: 3639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 3649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 3659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 366deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename T> 367deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void *getTag() { static int tag; return &tag; } 3683fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 3693fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 3703fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 371769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckerDtor> CheckerDtors; 372769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 3739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis struct DeclCheckerInfo { 3749fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CheckDeclFunc CheckFn; 3759fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis HandlesDeclFunc IsForDeclFn; 3769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis }; 3779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis std::vector<DeclCheckerInfo> DeclCheckers; 3789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 379769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckDeclFunc> BodyCheckers; 3809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 381769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 3829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 3839fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckersMapTy CachedDeclCheckersMap; 384769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 385769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct StmtCheckerInfo { 386769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtFunc CheckFn; 387769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc IsForStmtFn; 388769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 389769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 390769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<StmtCheckerInfo> StmtCheckers; 391769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 392769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CachedStmtCheckersKey { 393769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis unsigned StmtKind; 394769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 395769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 396769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 397769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 398769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 399769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 400769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static CachedStmtCheckersKey getSentinel() { 401fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis return CachedStmtCheckersKey(~0U, 0); 402769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 403769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis unsigned getHashValue() const { 404769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis llvm::FoldingSetNodeID ID; 405769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ID.AddInteger(StmtKind); 406769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ID.AddBoolean(IsPreVisit); 407769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return ID.ComputeHash(); 408769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 409769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool operator==(const CachedStmtCheckersKey &RHS) const { 410769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 411769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 412769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 413769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 414769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 415769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 416769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 417769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy; 418769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy CachedStmtCheckersMap; 419769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 420769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 421769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 422769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 423769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 424769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 425769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckLocationFunc> LocationCheckers; 42630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 427312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<CheckBindFunc> BindCheckers; 428312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 42930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 430e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 431af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis std::vector<CheckEndPathFunc> EndPathCheckers; 432af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 433cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 434cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 435183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 436183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 437183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 438183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 439183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis struct RegionChangesCheckerInfo { 440183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckRegionChangesFunc CheckFn; 441183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc WantUpdateFn; 442183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 443183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 444183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 445312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<EvalAssumeFunc> EvalAssumeCheckers; 446312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 447e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis std::vector<EvalCallFunc> EvalCallCheckers; 448deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 449deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis struct EventInfo { 450deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis llvm::SmallVector<CheckEventFunc, 4> Checkers; 451deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis bool HasDispatcher; 452deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo() : HasDispatcher(false) { } 453deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis }; 454deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 455deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 456deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventsTy Events; 45743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}; 45843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 45943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace 46043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 46143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace 46243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 463769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm { 464769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 465769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// in DenseMap and DenseSets. 466769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <> 467769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 468769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static inline clang::ento::CheckerManager::CachedStmtCheckersKey 469769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getEmptyKey() { 470769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return clang::ento::CheckerManager::CachedStmtCheckersKey(); 471769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 472769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static inline clang::ento::CheckerManager::CachedStmtCheckersKey 473769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getTombstoneKey() { 474769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 475769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 476769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 477769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static unsigned 478769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 479769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return S.getHashValue(); 480769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 481769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 482769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 483769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 484769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return LHS == RHS; 485769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 486769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 487769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm 488769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 48943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif 490