CheckerManager.cpp revision dbd658e139b3e0bf084f75feaea8d844af9e319f
143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===--- CheckerManager.cpp - Static Analyzer Checker Manager -------------===// 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#include "clang/StaticAnalyzer/Core/CheckerManager.h" 15ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "clang/StaticAnalyzer/Core/Checker.h" 16769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 17769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "clang/Analysis/ProgramPoint.h" 189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "clang/AST/DeclBase.h" 1943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 2043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace clang; 2143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace ento; 2243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 23d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidisbool CheckerManager::hasPathSensitiveCheckers() const { 24d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis return !StmtCheckers.empty() || 25d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !PreObjCMessageCheckers.empty() || 26d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !PostObjCMessageCheckers.empty() || 27d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !LocationCheckers.empty() || 28d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !BindCheckers.empty() || 29d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EndAnalysisCheckers.empty() || 30d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EndPathCheckers.empty() || 31d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !BranchConditionCheckers.empty() || 32d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !LiveSymbolsCheckers.empty() || 33d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !DeadSymbolsCheckers.empty() || 34d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !RegionChangesCheckers.empty() || 35d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EvalAssumeCheckers.empty() || 36d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EvalCallCheckers.empty(); 37d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis} 38d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis 39deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisvoid CheckerManager::finishedCheckerRegistration() { 40deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis#ifndef NDEBUG 41deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis // Make sure that for every event that has listeners, there is at least 42deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis // one dispatcher registered for it. 43deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis for (llvm::DenseMap<EventTag, EventInfo>::iterator 44deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis I = Events.begin(), E = Events.end(); I != E; ++I) 45deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis assert(I->second.HasDispatcher && "No dispatcher registered for an event"); 46deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis#endif 47deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis} 48deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 49769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 50769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing.. 51769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 52769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR) { 559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis assert(D); 569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis unsigned DeclKind = D->getKind(); 589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckers *checkers = 0; 599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind); 609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis if (CCI != CachedDeclCheckersMap.end()) { 619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis checkers = &(CCI->second); 629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } else { 639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Find the checkers that should run for this Decl and cache them. 649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis checkers = &CachedDeclCheckersMap[DeclKind]; 659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) { 669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis DeclCheckerInfo &info = DeclCheckers[i]; 679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis if (info.IsForDeclFn(D)) 68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers->push_back(info.CheckFn); 699fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 709fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 729fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis assert(checkers); 739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis for (CachedDeclCheckers::iterator 74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis I = checkers->begin(), E = checkers->end(); I != E; ++I) 75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis (*I)(D, mgr, BR); 769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR) { 809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis assert(D && D->hasBody()); 819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 82769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i) 83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis BodyCheckers[i](D, mgr, BR); 84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking. 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename CHECK_CTX> 91c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidisstatic void expandGraphWithCheckers(CHECK_CTX checkCtx, 92c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis ExplodedNodeSet &Dst, 93cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src) { 94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 95e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis typename CHECK_CTX::CheckersTy::const_iterator 96e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis I = checkCtx.checkers_begin(), E = checkCtx.checkers_end(); 97e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (I == E) { 98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Dst.insert(Src); 99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return; 100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 102cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet Tmp1, Tmp2; 103cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet *PrevSet = &Src; 104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 105e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis for (; I != E; ++I) { 106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet *CurrSet = 0; 107769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (I+1 == E) 108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CurrSet = &Dst; 109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis else { 110cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1; 111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CurrSet->clear(); 112769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end(); 115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis NI != NE; ++NI) 116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkCtx.runChecker(*I, *CurrSet, *NI); 117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // Update which NodeSet is the current one. 119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis PrevSet = CurrSet; 1209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 1219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 1229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace { 124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CheckStmtContext { 1255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVectorImpl<CheckerManager::CheckStmtFunc> CheckersTy; 126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const CheckersTy &Checkers; 128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S; 129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng; 130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 131e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 132e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 133e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtContext(bool isPreVisit, const CheckersTy &checkers, 135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *s, ExprEngine &eng) 136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { } 137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runChecker(CheckerManager::CheckStmtFunc checkFn, 139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, ExplodedNode *Pred) { 140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // FIXME: Remove respondsToCallback from CheckerContext; 141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker, 142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis IsPreVisit ? ProgramPoint::PreStmtKind : 143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ProgramPoint::PostStmtKind, 0, S); 144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkFn(S, C); 145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting Stmts. 150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForStmt(bool isPreVisit, 151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, 152cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 155769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtContext C(isPreVisit, *getCachedStmtCheckersFor(S, isPreVisit), 156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis S, Eng); 157c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace { 161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CheckObjCMessageContext { 162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy; 163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const CheckersTy &Checkers; 165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &Msg; 166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng; 167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 168e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 169e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 170e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers, 172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, ExprEngine &eng) 173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { } 174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runChecker(CheckerManager::CheckObjCMessageFunc checkFn, 176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, ExplodedNode *Pred) { 177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker, 178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis IsPreVisit ? ProgramPoint::PreStmtKind : 179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ProgramPoint::PostStmtKind, 0, 180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Msg.getOriginExpr()); 181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkFn(Msg, C); 182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting obj-c messages. 187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForObjCMessage(bool isPreVisit, 188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, 189cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 1923f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis CheckObjCMessageContext C(isPreVisit, 1933f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis isPreVisit ? PreObjCMessageCheckers 1943f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis : PostObjCMessageCheckers, 1953f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis msg, Eng); 196c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace { 200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CheckLocationContext { 201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckLocationFunc> CheckersTy; 202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const CheckersTy &Checkers; 203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal Loc; 204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsLoad; 205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S; 206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng; 207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 208e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 209e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 210e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 211769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckLocationContext(const CheckersTy &checkers, 2129c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis SVal loc, bool isLoad, const Stmt *s, ExprEngine &eng) 2139c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis : Checkers(checkers), Loc(loc), IsLoad(isLoad), S(s), Eng(eng) { } 214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runChecker(CheckerManager::CheckLocationFunc checkFn, 216769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, ExplodedNode *Pred) { 217769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker, 218769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis IsLoad ? ProgramPoint::PreLoadKind : 2199c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis ProgramPoint::PreStoreKind, 0, S); 220769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkFn(Loc, IsLoad, C); 221769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 222769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 2239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 2249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 225769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for load/store of a location. 226769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst, 227cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 228769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal location, bool isLoad, 2299c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis const Stmt *S, ExprEngine &Eng) { 2309c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis CheckLocationContext C(LocationCheckers, location, isLoad, S, Eng); 231c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 2329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 2339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 234312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisnamespace { 235312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis struct CheckBindContext { 236312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckBindFunc> CheckersTy; 237312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const CheckersTy &Checkers; 238312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Loc; 239312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Val; 240312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const Stmt *S; 241312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ExprEngine &Eng; 242312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 243312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 244312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 245312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 246312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckBindContext(const CheckersTy &checkers, 247312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal loc, SVal val, const Stmt *s, ExprEngine &eng) 248312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng) { } 249312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 250312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void runChecker(CheckerManager::CheckBindFunc checkFn, 251312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ExplodedNodeSet &Dst, ExplodedNode *Pred) { 252312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker, 253312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ProgramPoint::PreStmtKind, 0, S); 254312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis checkFn(Loc, Val, C); 255312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 256312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis }; 257312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 258312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 259312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis/// \brief Run checkers for binding of a value to a location. 260312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst, 261312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const ExplodedNodeSet &Src, 262312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal location, SVal val, 263312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const Stmt *S, ExprEngine &Eng) { 264312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckBindContext C(BindCheckers, location, val, S, Eng); 265312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 266312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 267312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 26830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G, 26930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis BugReporter &BR, 27030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis ExprEngine &Eng) { 27130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis for (unsigned i = 0, e = EndAnalysisCheckers.size(); i != e; ++i) 27230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis EndAnalysisCheckers[i](G, BR, Eng); 27330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis} 27430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 275af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis/// \brief Run checkers for end of path. 276af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisvoid CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B, 277af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis ExprEngine &Eng) { 278af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis for (unsigned i = 0, e = EndPathCheckers.size(); i != e; ++i) { 279af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis CheckEndPathFunc fn = EndPathCheckers[i]; 280af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis EndOfFunctionNodeBuilder specialB = B.withCheckerTag(fn.Checker); 281af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis fn(specialB, Eng); 282af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis } 283af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis} 284af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 285cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis/// \brief Run checkers for branch condition. 286cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisvoid CheckerManager::runCheckersForBranchCondition(const Stmt *condition, 287cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchNodeBuilder &B, 288cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis ExprEngine &Eng) { 289cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) { 290cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckBranchConditionFunc fn = BranchConditionCheckers[i]; 291cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis fn(condition, B, Eng); 292cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis } 293cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis} 294cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 295183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for live symbols. 29618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekvoid CheckerManager::runCheckersForLiveSymbols(const ProgramState *state, 297183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper) { 298183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (unsigned i = 0, e = LiveSymbolsCheckers.size(); i != e; ++i) 299183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis LiveSymbolsCheckers[i](state, SymReaper); 300183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 301183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 302183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisnamespace { 303183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis struct CheckDeadSymbolsContext { 304183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckDeadSymbolsFunc> CheckersTy; 305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const CheckersTy &Checkers; 306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SR; 307183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const Stmt *S; 308183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng; 309183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 310183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr, 314183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const Stmt *s, ExprEngine &eng) 315183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis : Checkers(checkers), SR(sr), S(s), Eng(eng) { } 316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn, 318183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExplodedNodeSet &Dst, ExplodedNode *Pred) { 319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker, 320183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ProgramPoint::PostPurgeDeadSymbolsKind, 0, S); 321183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis checkFn(SR, C); 322183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 323183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 324183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 325183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 326183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for dead symbols. 327183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 328183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const ExplodedNodeSet &Src, 329183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper, 330183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const Stmt *S, 331183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng) { 332183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng); 333183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 334183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 335183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 336183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief True if at least one checker wants to check region changes. 33718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekbool CheckerManager::wantsRegionChangeUpdate(const ProgramState *state) { 338183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) 339183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (RegionChangesCheckers[i].WantUpdateFn(state)) 340183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return true; 341183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 342183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return false; 343183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 344183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 345183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for region changes. 34618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState * 34718c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCheckerManager::runCheckersForRegionChanges(const ProgramState *state, 34835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const StoreManager::InvalidatedSymbols *invalidated, 349537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> ExplicitRegions, 350537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> Regions) { 351183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) { 352183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis // If any checker declares the state infeasible (or if it starts that way), 353183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis // bail out. 354183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (!state) 355183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return NULL; 356537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose state = RegionChangesCheckers[i].CheckFn(state, invalidated, 357537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ExplicitRegions, Regions); 358183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 359183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return state; 360183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 361183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 362312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis/// \brief Run checkers for handling assumptions on symbolic values. 36318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState * 36418c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCheckerManager::runCheckersForEvalAssume(const ProgramState *state, 365312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Cond, bool Assumption) { 366312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) { 367312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis // If any checker declares the state infeasible (or if it starts that way), 368312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis // bail out. 369312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis if (!state) 370312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return NULL; 371312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis state = EvalAssumeCheckers[i](state, Cond, Assumption); 372312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 373312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return state; 374312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 375312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 376e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// \brief Run checkers for evaluating a call. 377e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// Only one checker will evaluate the call. 378e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, 379e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const ExplodedNodeSet &Src, 380e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const CallExpr *CE, 381e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis ExprEngine &Eng, 382e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GraphExpander *defaultEval) { 383e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (EvalCallCheckers.empty() && defaultEval == 0) { 384e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Dst.insert(Src); 385e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis return; 386e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 387e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 388e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis for (ExplodedNodeSet::iterator 389e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) { 390e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 391e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis ExplodedNode *Pred = *NI; 392e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis bool anyEvaluated = false; 393e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis for (std::vector<EvalCallFunc>::iterator 394e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end(); 395e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EI != EE; ++EI) { 396e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis ExplodedNodeSet checkDst; 397e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, EI->Checker, 398e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis ProgramPoint::PostStmtKind, 0, CE); 399e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis bool evaluated = (*EI)(CE, C); 400e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis assert(!(evaluated && anyEvaluated) 401e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis && "There are more than one checkers evaluating the call"); 402e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (evaluated) { 403e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis anyEvaluated = true; 404e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Dst.insert(checkDst); 405e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#ifdef NDEBUG 406e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis break; // on release don't check that no other checker also evals. 407e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#endif 408e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 409e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 410e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 411e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (!anyEvaluated) { 412e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (defaultEval) 413e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis defaultEval->expandGraph(Dst, Pred); 414e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis else 415e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Dst.insert(Pred); 416e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 417e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 418e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} 419e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 4209be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek/// \brief Run checkers for the entire Translation Unit. 4219be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid CheckerManager::runCheckersOnEndOfTranslationUnit( 4229be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek const TranslationUnitDecl *TU, 4239be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek AnalysisManager &mgr, 4249be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek BugReporter &BR) { 4259be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek for (unsigned i = 0, e = EndOfTranslationUnitCheckers.size(); i != e; ++i) 4269be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek EndOfTranslationUnitCheckers[i](TU, mgr, BR); 4279be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek} 4289be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 429dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rosevoid CheckerManager::runCheckersForPrintState(raw_ostream &Out, 430dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const ProgramState *State, 431dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const char *NL, const char *Sep) { 432dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose for (llvm::DenseMap<CheckerTag, CheckerRef>::iterator 433dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose I = CheckerTags.begin(), E = CheckerTags.end(); I != E; ++I) 434dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose I->second->printState(Out, State, NL, Sep); 435dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose} 436dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose 437769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing. 439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 440769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForDecl(CheckDeclFunc checkfn, 442769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesDeclFunc isForDeclFn) { 443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis DeclCheckerInfo info = { checkfn, isForDeclFn }; 444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis DeclCheckers.push_back(info); 445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 447769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForBody(CheckDeclFunc checkfn) { 448769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis BodyCheckers.push_back(checkfn); 449769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 451769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 452769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking. 453769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 454769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 455769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn, 456769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn) { 457769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true }; 458769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckers.push_back(info); 459769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 460769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn, 461769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn) { 462769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false }; 463769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckers.push_back(info); 464769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 465769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 466769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreObjCMessage(CheckObjCMessageFunc checkfn) { 467769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis PreObjCMessageCheckers.push_back(checkfn); 468769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 469769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostObjCMessage(CheckObjCMessageFunc checkfn) { 470769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis PostObjCMessageCheckers.push_back(checkfn); 471769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 472769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 473769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForLocation(CheckLocationFunc checkfn) { 474769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis LocationCheckers.push_back(checkfn); 475769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 476769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 477312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::_registerForBind(CheckBindFunc checkfn) { 478312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis BindCheckers.push_back(checkfn); 479312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 480312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 48130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) { 48230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis EndAnalysisCheckers.push_back(checkfn); 48330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis} 48430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 485af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisvoid CheckerManager::_registerForEndPath(CheckEndPathFunc checkfn) { 486af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis EndPathCheckers.push_back(checkfn); 487af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis} 488af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 489cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisvoid CheckerManager::_registerForBranchCondition( 490cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckBranchConditionFunc checkfn) { 491cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchConditionCheckers.push_back(checkfn); 492cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis} 493cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 494183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForLiveSymbols(CheckLiveSymbolsFunc checkfn) { 495183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis LiveSymbolsCheckers.push_back(checkfn); 496183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 497183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 498183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForDeadSymbols(CheckDeadSymbolsFunc checkfn) { 499183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis DeadSymbolsCheckers.push_back(checkfn); 500183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 501183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 502183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForRegionChanges(CheckRegionChangesFunc checkfn, 503183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc wantUpdateFn) { 504183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis RegionChangesCheckerInfo info = {checkfn, wantUpdateFn}; 505183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis RegionChangesCheckers.push_back(info); 506183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 507183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 508312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::_registerForEvalAssume(EvalAssumeFunc checkfn) { 509312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis EvalAssumeCheckers.push_back(checkfn); 510312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 511312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 512e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) { 513e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EvalCallCheckers.push_back(checkfn); 514e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} 515e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 5169be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid CheckerManager::_registerForEndOfTranslationUnit( 5179be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek CheckEndOfTranslationUnit checkfn) { 5189be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek EndOfTranslationUnitCheckers.push_back(checkfn); 5199be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek} 5209be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 521769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 522769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details. 523769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 524769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 525769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::CachedStmtCheckers * 526769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) { 527769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis assert(S); 528769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 529769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey key(S->getStmtClass(), isPreVisit); 530769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckers *checkers = 0; 531769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy::iterator CCI = CachedStmtCheckersMap.find(key); 532769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (CCI != CachedStmtCheckersMap.end()) { 533769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers = &(CCI->second); 534769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } else { 535769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // Find the checkers that should run for this Stmt and cache them. 536769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers = &CachedStmtCheckersMap[key]; 537769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (unsigned i = 0, e = StmtCheckers.size(); i != e; ++i) { 538769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckerInfo &info = StmtCheckers[i]; 539769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (info.IsPreVisit == isPreVisit && info.IsForStmtFn(S)) 540769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers->push_back(info.CheckFn); 541769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 5429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 543769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 544769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis assert(checkers); 545769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return checkers; 546769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 547769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 548769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::~CheckerManager() { 549769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (unsigned i = 0, e = CheckerDtors.size(); i != e; ++i) 550769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerDtors[i](); 5519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 5529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 55343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Anchor for the vtable. 554e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisGraphExpander::~GraphExpander() { } 555