CheckerManager.h revision 686775deca8b8685eb90801495880e3abdd844c2
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" 2135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include <vector> 2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 2443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace clang { 259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class Decl; 26769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class Stmt; 27e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis class CallExpr; 2843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 2943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace ento { 3043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis class ExprEngine; 319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class AnalysisManager; 329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class BugReporter; 33769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class CheckerContext; 34769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class ObjCMessage; 35769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class SVal; 36e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis class ExplodedNode; 37769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class ExplodedNodeSet; 3830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis class ExplodedGraph; 39769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis class GRState; 40af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis class EndOfFunctionNodeBuilder; 41cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis class BranchNodeBuilder; 42183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis class MemRegion; 43183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis class SymbolReaper; 44769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 45e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass GraphExpander { 46e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic: 47e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis virtual ~GraphExpander(); 48e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0; 49e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}; 50e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 514d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn; 524d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 5335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenektemplate <typename RET, typename P1, typename P2, typename P3, typename P4> 5435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekclass CheckerFn<RET(P1, P2, P3, P4)> { 5535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek typedef RET (*Func)(void *, P1, P2, P3, P4); 5635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek Func Fn; 5735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekpublic: 5835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek void *Checker; 5935bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 6035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 6135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek return Fn(Checker, p1, p2, p3, p4); 6235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek } 6335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek}; 6435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek 654d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3> 664d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> { 674d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *, P1, P2, P3); 68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 69769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 724d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 73769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2> 764d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> { 774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *, P1, P2); 78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1> 864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> { 874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *, P1); 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()(P1 p1) const { return Fn(Checker, p1); } 93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET> 964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> { 974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef RET (*Func)(void *); 98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Func Fn; 99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void *Checker; 101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 1024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis RET operator()() const { return Fn(Checker); } 103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 10443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 10543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager { 1062e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis const LangOptions LangOpts; 1072e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis 10843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic: 1092e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 1109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis ~CheckerManager(); 1119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 112d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis bool hasPathSensitiveCheckers() const; 113d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis 114deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void finishedCheckerRegistration(); 115deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 1162e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis const LangOptions &getLangOptions() const { return LangOpts; } 1172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis 1189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef void *CheckerRef; 1193fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis typedef void *CheckerTag; 1204d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void ()> CheckerDtor; 1219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker 1249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Used to register checkers. 1273fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis /// 1283fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis /// \returns a pointer to the checker object. 1299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 1303fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis CHECKER *registerChecker() { 131deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CheckerTag tag = getTag<CHECKER>(); 1323fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis CheckerRef &ref = CheckerTags[tag]; 1333fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis if (ref) 1343fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis return static_cast<CHECKER *>(ref); // already registered. 1353fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 1369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECKER *checker = new CHECKER(); 137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 1389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECKER::_register(checker, *this); 1393fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis ref = checker; 1403fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis return checker; 1419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 14243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 1439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing.. 1459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 1469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Run checkers handling Decls. 1489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 1499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR); 1509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis /// \brief Run checkers handling Decls containing a Stmt body. 1529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 1539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR); 1549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 1559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking. 157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for pre-visiting Stmts. 160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPreStmt(ExplodedNodeSet &Dst, 161cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for post-visiting Stmts. 168769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPostStmt(ExplodedNodeSet &Dst, 169cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng); 173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for visiting Stmts. 176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForStmt(bool isPreVisit, 177cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng); 179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for pre-visiting obj-c messages. 181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 182cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for post-visiting obj-c messages. 189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 190cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng); 194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 196769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for visiting obj-c messages. 197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForObjCMessage(bool isPreVisit, 198cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet &Dst, 199cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, ExprEngine &Eng); 201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// \brief Run checkers for load/store of a location. 203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runCheckersForLocation(ExplodedNodeSet &Dst, 204cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal location, bool isLoad, 206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng); 208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 209312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis /// \brief Run checkers for binding of a value to a location. 210312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void runCheckersForBind(ExplodedNodeSet &Dst, 211312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const ExplodedNodeSet &Src, 212312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal location, SVal val, 213312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng); 214312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 21530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis /// \brief Run checkers for end of analysis. 21630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 21730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis ExprEngine &Eng); 21830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 219af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis /// \brief Run checkers for end of path. 220af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng); 221af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 222cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis /// \brief Run checkers for branch condition. 223cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis void runCheckersForBranchCondition(const Stmt *condition, 224cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchNodeBuilder &B, ExprEngine &Eng); 225cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 226183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for live symbols. 227183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runCheckersForLiveSymbols(const GRState *state, 228183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper); 229183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 230183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for dead symbols. 231183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 232183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const ExplodedNodeSet &Src, 233183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper, const Stmt *S, 234183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng); 235183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 236183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief True if at least one checker wants to check region changes. 237183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis bool wantsRegionChangeUpdate(const GRState *state); 238183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 239183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis /// \brief Run checkers for region changes. 24035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const GRState * 24135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek runCheckersForRegionChanges(const GRState *state, 24235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const StoreManager::InvalidatedSymbols *invalidated, 24335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const MemRegion * const *Begin, 24435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const MemRegion * const *End); 245183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 246312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis /// \brief Run checkers for handling assumptions on symbolic values. 247312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const GRState *runCheckersForEvalAssume(const GRState *state, 248312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Cond, bool Assumption); 249312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 250e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis /// \brief Run checkers for evaluating a call. 251e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void runCheckersForEvalCall(ExplodedNodeSet &Dst, 252e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const ExplodedNodeSet &Src, 253e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const CallExpr *CE, ExprEngine &Eng, 254e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GraphExpander *defaultEval = 0); 2559be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 2569be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek /// \brief Run checkers for the entire Translation Unit. 2579be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl* TU, 2589be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek AnalysisManager &mgr, 2599be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek BugReporter &BR); 260e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 261769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 262769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing. 2639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 2649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 2659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Functions used by the registration mechanism, checkers should not touch 2669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // these directly. 2679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 2684d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)> 269769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckDeclFunc; 270769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 2719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef bool (*HandlesDeclFunc)(const Decl *D); 272769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 2739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 274769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForBody(CheckDeclFunc checkfn); 275769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 276769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 277769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking. 278769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 279769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 2804d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; 2814d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)> 2834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckObjCMessageFunc; 2844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const SVal &location, bool isLoad, CheckerContext &)> 286769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckLocationFunc; 2874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2884d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const SVal &location, const SVal &val, 2894d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckerContext &)> CheckBindFunc; 2904d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2914d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> 29230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis CheckEndAnalysisFunc; 2934d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2944d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)> 2954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckEndPathFunc; 2964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 2974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const Stmt *, BranchNodeBuilder &, ExprEngine &)> 298cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckBranchConditionFunc; 2994d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 3004d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> 3014d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckDeadSymbolsFunc; 3024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 3034d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc; 3044d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 3054d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<const GRState * (const GRState *, 30635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const StoreManager::InvalidatedSymbols *symbols, 3074d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis const MemRegion * const *begin, 3084d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis const MemRegion * const *end)> 3094d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis CheckRegionChangesFunc; 3104d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 3114d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<bool (const GRState *)> WantsRegionChangeUpdateFunc; 3124d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 3134d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<const GRState * (const GRState *, 3144d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis const SVal &cond, bool assumption)> 3154d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis EvalAssumeFunc; 3164d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis 3174d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> 3184d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis EvalCallFunc; 319769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 3209be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek typedef CheckerFn<void (const TranslationUnitDecl *, 3219be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek AnalysisManager&, BugReporter &)> 3229be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek CheckEndOfTranslationUnit; 3239be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 324769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef bool (*HandlesStmtFunc)(const Stmt *D); 325769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPreStmt(CheckStmtFunc checkfn, 326769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn); 327769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPostStmt(CheckStmtFunc checkfn, 328769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn); 329769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 330769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 331769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 332769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 333769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void _registerForLocation(CheckLocationFunc checkfn); 334769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 335312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void _registerForBind(CheckBindFunc checkfn); 336312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 33730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 33830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 339af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis void _registerForEndPath(CheckEndPathFunc checkfn); 340af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 341cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 342cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 343183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 344183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 345183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 346183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 347183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 348183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc wantUpdateFn); 349183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 350312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void _registerForEvalAssume(EvalAssumeFunc checkfn); 351312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 352e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis void _registerForEvalCall(EvalCallFunc checkfn); 353e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 3549be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); 3559be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 356769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 357deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events. 358deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 359deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 360deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef void *EventTag; 3614d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis typedef CheckerFn<void (const void *event)> CheckEventFunc; 362deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 363deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 364deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _registerListenerForEvent(CheckEventFunc checkfn) { 365deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo &info = Events[getTag<EVENT>()]; 366deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.Checkers.push_back(checkfn); 367deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 368deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 369deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 370deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _registerDispatcherForEvent() { 371deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo &info = Events[getTag<EVENT>()]; 372deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.HasDispatcher = true; 373deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 374deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 375deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename EVENT> 376deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void _dispatchEvent(const EVENT &event) const { 377deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 378deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis if (I == Events.end()) 379deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis return; 380deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis const EventInfo &info = I->second; 381deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 382deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis info.Checkers[i](&event); 383deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 384deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 385deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 386769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details. 387769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 38843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 38943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate: 3909fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 3919fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 3929fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 393deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename T> 394deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void *getTag() { static int tag; return &tag; } 3953fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 3963fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 3973fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis 398769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckerDtor> CheckerDtors; 399769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 4009fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis struct DeclCheckerInfo { 4019fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CheckDeclFunc CheckFn; 4029fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis HandlesDeclFunc IsForDeclFn; 4039fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis }; 4049fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis std::vector<DeclCheckerInfo> DeclCheckers; 4059fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 406769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckDeclFunc> BodyCheckers; 4079fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 408686775deca8b8685eb90801495880e3abdd844c2Chris Lattner typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 4099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 4109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckersMapTy CachedDeclCheckersMap; 411769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 412769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct StmtCheckerInfo { 413769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtFunc CheckFn; 414769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc IsForStmtFn; 415769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 416769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 417769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<StmtCheckerInfo> StmtCheckers; 418769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 419769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CachedStmtCheckersKey { 420769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis unsigned StmtKind; 421769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 422769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 423769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 424769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 425769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 426769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 427769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static CachedStmtCheckersKey getSentinel() { 428fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis return CachedStmtCheckersKey(~0U, 0); 429769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 430769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis unsigned getHashValue() const { 431769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis llvm::FoldingSetNodeID ID; 432769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ID.AddInteger(StmtKind); 433769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ID.AddBoolean(IsPreVisit); 434769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return ID.ComputeHash(); 435769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 436769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool operator==(const CachedStmtCheckersKey &RHS) const { 437769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 440769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 442686775deca8b8685eb90801495880e3abdd844c2Chris Lattner typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy; 445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy CachedStmtCheckersMap; 446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 447769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 448769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 449769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 451769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 452769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<CheckLocationFunc> LocationCheckers; 45330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 454312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<CheckBindFunc> BindCheckers; 455312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 45630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 457e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 458af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis std::vector<CheckEndPathFunc> EndPathCheckers; 459af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 460cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 461cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 462183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 463183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 464183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 465183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 466183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis struct RegionChangesCheckerInfo { 467183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckRegionChangesFunc CheckFn; 468183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc WantUpdateFn; 469183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 470183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 471183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 472312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<EvalAssumeFunc> EvalAssumeCheckers; 473312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 474e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis std::vector<EvalCallFunc> EvalCallCheckers; 475deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 4769be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; 4779be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 478deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis struct EventInfo { 479686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<CheckEventFunc, 4> Checkers; 480deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis bool HasDispatcher; 481deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventInfo() : HasDispatcher(false) { } 482deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis }; 483deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 484deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 485deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventsTy Events; 48643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}; 48743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 48843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace 48943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 49043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace 49143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 492769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm { 493769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 494769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis /// in DenseMap and DenseSets. 495769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <> 496769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 497769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static inline clang::ento::CheckerManager::CachedStmtCheckersKey 498769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getEmptyKey() { 499769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return clang::ento::CheckerManager::CachedStmtCheckersKey(); 500769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 501769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static inline clang::ento::CheckerManager::CachedStmtCheckersKey 502769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getTombstoneKey() { 503769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 504769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 505769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 506769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static unsigned 507769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 508769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return S.getHashValue(); 509769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 510769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 511769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 512769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 513769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return LHS == RHS; 514769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 515769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 516769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm 517769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 51843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif 519