CheckerManager.cpp revision 063e0887ad65d666d23ee3178436ad6507abbd1b
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" 17d1e5a89226da79f7e6f43d40facc46abda9e5245Jordy Rose#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 18769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "clang/Analysis/ProgramPoint.h" 199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "clang/AST/DeclBase.h" 2043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 2143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace clang; 2243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace ento; 2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis 24d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidisbool CheckerManager::hasPathSensitiveCheckers() const { 25d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis return !StmtCheckers.empty() || 26d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !PreObjCMessageCheckers.empty() || 27d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !PostObjCMessageCheckers.empty() || 28d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !LocationCheckers.empty() || 29d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !BindCheckers.empty() || 30d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EndAnalysisCheckers.empty() || 31d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EndPathCheckers.empty() || 32d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !BranchConditionCheckers.empty() || 33d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !LiveSymbolsCheckers.empty() || 34d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !DeadSymbolsCheckers.empty() || 35d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !RegionChangesCheckers.empty() || 36d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis !EvalAssumeCheckers.empty() || 37dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks !EvalCallCheckers.empty() || 38dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks !InlineCallCheckers.empty(); 39d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis} 40d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis 41deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisvoid CheckerManager::finishedCheckerRegistration() { 42deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis#ifndef NDEBUG 43deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis // Make sure that for every event that has listeners, there is at least 44deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis // one dispatcher registered for it. 45deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis for (llvm::DenseMap<EventTag, EventInfo>::iterator 46deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis I = Events.begin(), E = Events.end(); I != E; ++I) 47deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis assert(I->second.HasDispatcher && "No dispatcher registered for an event"); 48deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis#endif 49deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis} 50deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 51769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 52769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing.. 53769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 54769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR) { 579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis assert(D); 589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis unsigned DeclKind = D->getKind(); 609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckers *checkers = 0; 619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind); 629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis if (CCI != CachedDeclCheckersMap.end()) { 639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis checkers = &(CCI->second); 649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } else { 659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Find the checkers that should run for this Decl and cache them. 669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis checkers = &CachedDeclCheckersMap[DeclKind]; 679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) { 689fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis DeclCheckerInfo &info = DeclCheckers[i]; 699fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis if (info.IsForDeclFn(D)) 70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers->push_back(info.CheckFn); 719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 729fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 749fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis assert(checkers); 759fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis for (CachedDeclCheckers::iterator 76769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis I = checkers->begin(), E = checkers->end(); I != E; ++I) 77769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis (*I)(D, mgr, BR); 789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR) { 829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis assert(D && D->hasBody()); 839fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i) 85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis BodyCheckers[i](D, mgr, BR); 86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking. 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 92769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename CHECK_CTX> 93c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidisstatic void expandGraphWithCheckers(CHECK_CTX checkCtx, 94c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis ExplodedNodeSet &Dst, 95cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src) { 968ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext(); 978ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks if (Src.empty()) 988ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks return; 99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 100e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis typename CHECK_CTX::CheckersTy::const_iterator 101e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis I = checkCtx.checkers_begin(), E = checkCtx.checkers_end(); 102e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (I == E) { 103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Dst.insert(Src); 104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return; 105769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 107cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis ExplodedNodeSet Tmp1, Tmp2; 108cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet *PrevSet = &Src; 109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 110e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis for (; I != E; ++I) { 111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet *CurrSet = 0; 112769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (I+1 == E) 113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CurrSet = &Dst; 114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis else { 115cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1; 116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CurrSet->clear(); 117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 1198ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder B(*PrevSet, *CurrSet, BldrCtx); 120769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end(); 1218ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NI != NE; ++NI) { 1228ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks checkCtx.runChecker(*I, B, *NI); 1238ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks } 1248ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks 1258ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks // If all the produced transitions are sinks, stop. 1268ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks if (CurrSet->empty()) 1278ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks return; 1288ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks 129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // Update which NodeSet is the current one. 130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis PrevSet = CurrSet; 1319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 1329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 1339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace { 135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CheckStmtContext { 1365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVectorImpl<CheckerManager::CheckStmtFunc> CheckersTy; 137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const CheckersTy &Checkers; 139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S; 140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng; 141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 142e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 143e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 144e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtContext(bool isPreVisit, const CheckersTy &checkers, 146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *s, ExprEngine &eng) 147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { } 148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runChecker(CheckerManager::CheckStmtFunc checkFn, 1508ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder &Bldr, ExplodedNode *Pred) { 151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // FIXME: Remove respondsToCallback from CheckerContext; 1523f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind : 1533f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::PostStmtKind; 1543f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, 1553f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Pred->getLocationContext(), checkFn.Checker); 156063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 1573f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkFn(S, C); 159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting Stmts. 164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForStmt(bool isPreVisit, 165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, 166cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S, 168769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 169769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckStmtContext C(isPreVisit, *getCachedStmtCheckersFor(S, isPreVisit), 170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis S, Eng); 171c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace { 175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CheckObjCMessageContext { 176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy; 177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsPreVisit; 178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const CheckersTy &Checkers; 179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &Msg; 180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng; 181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 182e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 183e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 184e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers, 186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, ExprEngine &eng) 187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { } 188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runChecker(CheckerManager::CheckObjCMessageFunc checkFn, 1908ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder &Bldr, ExplodedNode *Pred) { 1913f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind : 1923f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::PostStmtKind; 1933f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint &L = ProgramPoint::getProgramPoint(Msg.getOriginExpr(), 1943f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks K, Pred->getLocationContext(), checkFn.Checker); 195063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 1963f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkFn(Msg, C); 198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting obj-c messages. 203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForObjCMessage(bool isPreVisit, 204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExplodedNodeSet &Dst, 205cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const ObjCMessage &msg, 207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng) { 2083f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis CheckObjCMessageContext C(isPreVisit, 2093f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis isPreVisit ? PreObjCMessageCheckers 2103f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis : PostObjCMessageCheckers, 2113f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis msg, Eng); 212c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 213769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace { 216769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis struct CheckLocationContext { 217769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckLocationFunc> CheckersTy; 218769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const CheckersTy &Checkers; 219769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal Loc; 220769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis bool IsLoad; 221769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const Stmt *S; 222769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ExprEngine &Eng; 223769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 224e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 225e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 226e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 227769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckLocationContext(const CheckersTy &checkers, 2289c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis SVal loc, bool isLoad, const Stmt *s, ExprEngine &eng) 2299c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis : Checkers(checkers), Loc(loc), IsLoad(isLoad), S(s), Eng(eng) { } 230769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 231769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis void runChecker(CheckerManager::CheckLocationFunc checkFn, 2328ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder &Bldr, ExplodedNode *Pred) { 2333f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::Kind K = IsLoad ? ProgramPoint::PreLoadKind : 2343f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::PreStoreKind; 2353f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, 2363f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Pred->getLocationContext(), checkFn.Checker); 237063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 2383f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 239390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks checkFn(Loc, IsLoad, S, C); 240769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 241769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis }; 2429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 2439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 244769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for load/store of a location. 245ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 246769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst, 247cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis const ExplodedNodeSet &Src, 248769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis SVal location, bool isLoad, 2499c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis const Stmt *S, ExprEngine &Eng) { 2509c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis CheckLocationContext C(LocationCheckers, location, isLoad, S, Eng); 251c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 2529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 2539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 254312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisnamespace { 255312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis struct CheckBindContext { 256312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckBindFunc> CheckersTy; 257312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const CheckersTy &Checkers; 258312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Loc; 259312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Val; 260312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const Stmt *S; 261312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ExprEngine &Eng; 262ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::Kind PointKind; 263312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 264312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 265312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 266312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 267312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckBindContext(const CheckersTy &checkers, 268ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks SVal loc, SVal val, const Stmt *s, ExprEngine &eng, 269ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::Kind PK) 270ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PointKind(PK) {} 271312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 272312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis void runChecker(CheckerManager::CheckBindFunc checkFn, 2738ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder &Bldr, ExplodedNode *Pred) { 274ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks const ProgramPoint &L = ProgramPoint::getProgramPoint(S, PointKind, 2753f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Pred->getLocationContext(), checkFn.Checker); 276063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 2773f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 278390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks checkFn(Loc, Val, S, C); 279312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 280312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis }; 281312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 282312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 283312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis/// \brief Run checkers for binding of a value to a location. 284312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst, 285312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const ExplodedNodeSet &Src, 286312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal location, SVal val, 287ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks const Stmt *S, ExprEngine &Eng, 288ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::Kind PointKind) { 289ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks CheckBindContext C(BindCheckers, location, val, S, Eng, PointKind); 290312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 291312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 292312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 29330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G, 29430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis BugReporter &BR, 29530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis ExprEngine &Eng) { 29630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis for (unsigned i = 0, e = EndAnalysisCheckers.size(); i != e; ++i) 29730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis EndAnalysisCheckers[i](G, BR, Eng); 29830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis} 29930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 300af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis/// \brief Run checkers for end of path. 301af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks// Note, We do not chain the checker output (like in expandGraphWithCheckers) 302af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks// for this callback since end of path nodes are expected to be final. 303af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaksvoid CheckerManager::runCheckersForEndPath(NodeBuilderContext &BC, 304af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks ExplodedNodeSet &Dst, 305af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis ExprEngine &Eng) { 306af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks ExplodedNode *Pred = BC.Pred; 307af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks 308af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks // We define the builder outside of the loop bacause if at least one checkers 309af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks // creates a sucsessor for Pred, we do not need to generate an 310af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks // autotransition for it. 311af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks NodeBuilder Bldr(Pred, Dst, BC); 312af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis for (unsigned i = 0, e = EndPathCheckers.size(); i != e; ++i) { 313af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks CheckEndPathFunc checkFn = EndPathCheckers[i]; 314af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks 315af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks const ProgramPoint &L = BlockEntrance(BC.Block, 316af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks Pred->getLocationContext(), 317af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks checkFn.Checker); 318063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 319af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks checkFn(C); 320af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis } 321af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis} 322af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 323f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaksnamespace { 324f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks struct CheckBranchConditionContext { 325f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks typedef std::vector<CheckerManager::CheckBranchConditionFunc> CheckersTy; 326f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks const CheckersTy &Checkers; 327f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks const Stmt *Condition; 328f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ExprEngine &Eng; 329f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 330f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 331f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 332f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 333f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks CheckBranchConditionContext(const CheckersTy &checkers, 334f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks const Stmt *Cond, ExprEngine &eng) 335f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks : Checkers(checkers), Condition(Cond), Eng(eng) {} 336f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 337f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks void runChecker(CheckerManager::CheckBranchConditionFunc checkFn, 338f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks NodeBuilder &Bldr, ExplodedNode *Pred) { 339f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ProgramPoint L = PostCondition(Condition, Pred->getLocationContext(), 340f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks checkFn.Checker); 341063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 342f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks checkFn(Condition, C); 343f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks } 344f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks }; 345f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks} 346f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 347cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis/// \brief Run checkers for branch condition. 348f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaksvoid CheckerManager::runCheckersForBranchCondition(const Stmt *Condition, 349f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ExplodedNodeSet &Dst, 3504e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks ExplodedNode *Pred, 351cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis ExprEngine &Eng) { 352f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ExplodedNodeSet Src; 353f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks Src.insert(Pred); 354f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks CheckBranchConditionContext C(BranchConditionCheckers, Condition, Eng); 355f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks expandGraphWithCheckers(C, Dst, Src); 356cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis} 357cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 358183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for live symbols. 35918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekvoid CheckerManager::runCheckersForLiveSymbols(const ProgramState *state, 360183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper) { 361183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (unsigned i = 0, e = LiveSymbolsCheckers.size(); i != e; ++i) 362183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis LiveSymbolsCheckers[i](state, SymReaper); 363183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 364183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 365183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisnamespace { 366183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis struct CheckDeadSymbolsContext { 367183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis typedef std::vector<CheckerManager::CheckDeadSymbolsFunc> CheckersTy; 368183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const CheckersTy &Checkers; 369183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SR; 370183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const Stmt *S; 371183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng; 372183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 373183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } 374183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckersTy::const_iterator checkers_end() { return Checkers.end(); } 375183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 376183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr, 377183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const Stmt *s, ExprEngine &eng) 378183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis : Checkers(checkers), SR(sr), S(s), Eng(eng) { } 379183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 380183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn, 3818ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder &Bldr, ExplodedNode *Pred) { 3823f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::Kind K = ProgramPoint::PostPurgeDeadSymbolsKind; 3833f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, 3843f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Pred->getLocationContext(), checkFn.Checker); 385063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(Bldr, Eng, Pred, L); 3863f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 387183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis checkFn(SR, C); 388183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 389183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis }; 390183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 391183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 392183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for dead symbols. 393183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 394183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const ExplodedNodeSet &Src, 395183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SymReaper, 396183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const Stmt *S, 397183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ExprEngine &Eng) { 398183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng); 399183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis expandGraphWithCheckers(C, Dst, Src); 400183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 401183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 402183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief True if at least one checker wants to check region changes. 40318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekbool CheckerManager::wantsRegionChangeUpdate(const ProgramState *state) { 404183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) 405183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (RegionChangesCheckers[i].WantUpdateFn(state)) 406183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return true; 407183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 408183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return false; 409183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 410183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 411183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for region changes. 41218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState * 41318c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCheckerManager::runCheckersForRegionChanges(const ProgramState *state, 41435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const StoreManager::InvalidatedSymbols *invalidated, 415537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> ExplicitRegions, 416537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> Regions) { 417183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) { 418183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis // If any checker declares the state infeasible (or if it starts that way), 419183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis // bail out. 420183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (!state) 421183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return NULL; 422537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose state = RegionChangesCheckers[i].CheckFn(state, invalidated, 423537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ExplicitRegions, Regions); 424183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 425183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return state; 426183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 427183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 428312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis/// \brief Run checkers for handling assumptions on symbolic values. 42918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState * 43018c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCheckerManager::runCheckersForEvalAssume(const ProgramState *state, 431312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis SVal Cond, bool Assumption) { 432312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) { 433312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis // If any checker declares the state infeasible (or if it starts that way), 434312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis // bail out. 435312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis if (!state) 436312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return NULL; 437312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis state = EvalAssumeCheckers[i](state, Cond, Assumption); 438312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 439312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return state; 440312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 441312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 442e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// \brief Run checkers for evaluating a call. 443e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// Only one checker will evaluate the call. 444e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, 445e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const ExplodedNodeSet &Src, 446e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis const CallExpr *CE, 447e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis ExprEngine &Eng, 448e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GraphExpander *defaultEval) { 449dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks if (EvalCallCheckers.empty() && 450dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks InlineCallCheckers.empty() && 451dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks defaultEval == 0) { 452e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Dst.insert(Src); 453e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis return; 454e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 455e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 456e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis for (ExplodedNodeSet::iterator 457e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) { 458e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 459e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis ExplodedNode *Pred = *NI; 460e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis bool anyEvaluated = false; 461dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks 462dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks // First, check if any of the InlineCall callbacks can evaluate the call. 463dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks assert(InlineCallCheckers.size() <= 1 && 464dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks "InlineCall is a special hacky callback to allow intrusive" 465dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks "evaluation of the call (which simulates inlining). It is " 466dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks "currently only used by OSAtomicChecker and should go away " 467dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks "at some point."); 468dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks for (std::vector<InlineCallFunc>::iterator 469dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks EI = InlineCallCheckers.begin(), EE = InlineCallCheckers.end(); 470dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks EI != EE; ++EI) { 471dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks ExplodedNodeSet checkDst; 472dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks bool evaluated = (*EI)(CE, Eng, Pred, checkDst); 473dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks assert(!(evaluated && anyEvaluated) 474dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks && "There are more than one checkers evaluating the call"); 475dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks if (evaluated) { 476dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks anyEvaluated = true; 477dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks Dst.insert(checkDst); 478dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks#ifdef NDEBUG 479dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks break; // on release don't check that no other checker also evals. 480dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks#endif 481dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks } 482dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks } 483dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks 484dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks#ifdef NDEBUG // on release don't check that no other checker also evals. 485dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks if (anyEvaluated) { 486dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks break; 487dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks } 488dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks#endif 489dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks 4908ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks ExplodedNodeSet checkDst; 4918ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks NodeBuilder B(Pred, checkDst, Eng.getBuilderContext()); 492dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks // Next, check if any of the EvalCall callbacks can evaluate the call. 493e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis for (std::vector<EvalCallFunc>::iterator 494e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end(); 495e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EI != EE; ++EI) { 4963f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ProgramPoint::Kind K = ProgramPoint::PostStmtKind; 4973f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint &L = ProgramPoint::getProgramPoint(CE, K, 4983f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Pred->getLocationContext(), EI->Checker); 499b1576f7136163ce3efd6dcf5a3e53e1c8ec6520cAnna Zaks bool evaluated = false; 500b1576f7136163ce3efd6dcf5a3e53e1c8ec6520cAnna Zaks { // CheckerContext generates transitions(populates checkDest) on 501b1576f7136163ce3efd6dcf5a3e53e1c8ec6520cAnna Zaks // destruction, so introduce the scope to make sure it gets properly 502b1576f7136163ce3efd6dcf5a3e53e1c8ec6520cAnna Zaks // populated. 503063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks CheckerContext C(B, Eng, Pred, L); 504b1576f7136163ce3efd6dcf5a3e53e1c8ec6520cAnna Zaks evaluated = (*EI)(CE, C); 505b1576f7136163ce3efd6dcf5a3e53e1c8ec6520cAnna Zaks } 506e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis assert(!(evaluated && anyEvaluated) 507e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis && "There are more than one checkers evaluating the call"); 508e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (evaluated) { 509e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis anyEvaluated = true; 510e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Dst.insert(checkDst); 511e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#ifdef NDEBUG 512e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis break; // on release don't check that no other checker also evals. 513e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#endif 514e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 515e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 516e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 517dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks // If none of the checkers evaluated the call, ask ExprEngine to handle it. 518e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (!anyEvaluated) { 519e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis if (defaultEval) 520e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis defaultEval->expandGraph(Dst, Pred); 521e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis else 522e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis Dst.insert(Pred); 523e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 524e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 525e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} 526e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 5279be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek/// \brief Run checkers for the entire Translation Unit. 5289be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid CheckerManager::runCheckersOnEndOfTranslationUnit( 5299be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek const TranslationUnitDecl *TU, 5309be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek AnalysisManager &mgr, 5319be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek BugReporter &BR) { 5329be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek for (unsigned i = 0, e = EndOfTranslationUnitCheckers.size(); i != e; ++i) 5339be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek EndOfTranslationUnitCheckers[i](TU, mgr, BR); 5349be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek} 5359be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 536dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rosevoid CheckerManager::runCheckersForPrintState(raw_ostream &Out, 537dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const ProgramState *State, 538dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const char *NL, const char *Sep) { 539dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose for (llvm::DenseMap<CheckerTag, CheckerRef>::iterator 540dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose I = CheckerTags.begin(), E = CheckerTags.end(); I != E; ++I) 541dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose I->second->printState(Out, State, NL, Sep); 542dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose} 543dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose 544769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 545769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing. 546769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 547769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 548769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForDecl(CheckDeclFunc checkfn, 549769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesDeclFunc isForDeclFn) { 550769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis DeclCheckerInfo info = { checkfn, isForDeclFn }; 551769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis DeclCheckers.push_back(info); 552769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 553769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 554769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForBody(CheckDeclFunc checkfn) { 555769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis BodyCheckers.push_back(checkfn); 556769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 557769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 558769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 559769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking. 560769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 561769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 562769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn, 563769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn) { 564769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true }; 565769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckers.push_back(info); 566769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 567769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn, 568769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis HandlesStmtFunc isForStmtFn) { 569769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false }; 570769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckers.push_back(info); 571769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 572769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 573769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreObjCMessage(CheckObjCMessageFunc checkfn) { 574769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis PreObjCMessageCheckers.push_back(checkfn); 575769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 576769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostObjCMessage(CheckObjCMessageFunc checkfn) { 577769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis PostObjCMessageCheckers.push_back(checkfn); 578769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 579769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 580769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForLocation(CheckLocationFunc checkfn) { 581769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis LocationCheckers.push_back(checkfn); 582769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 583769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 584312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::_registerForBind(CheckBindFunc checkfn) { 585312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis BindCheckers.push_back(checkfn); 586312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 587312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 58830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) { 58930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis EndAnalysisCheckers.push_back(checkfn); 59030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis} 59130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 592af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisvoid CheckerManager::_registerForEndPath(CheckEndPathFunc checkfn) { 593af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis EndPathCheckers.push_back(checkfn); 594af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis} 595af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 596cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisvoid CheckerManager::_registerForBranchCondition( 597cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckBranchConditionFunc checkfn) { 598cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchConditionCheckers.push_back(checkfn); 599cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis} 600cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 601183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForLiveSymbols(CheckLiveSymbolsFunc checkfn) { 602183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis LiveSymbolsCheckers.push_back(checkfn); 603183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 604183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 605183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForDeadSymbols(CheckDeadSymbolsFunc checkfn) { 606183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis DeadSymbolsCheckers.push_back(checkfn); 607183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 608183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 609183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForRegionChanges(CheckRegionChangesFunc checkfn, 610183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis WantsRegionChangeUpdateFunc wantUpdateFn) { 611183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis RegionChangesCheckerInfo info = {checkfn, wantUpdateFn}; 612183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis RegionChangesCheckers.push_back(info); 613183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 614183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 615312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::_registerForEvalAssume(EvalAssumeFunc checkfn) { 616312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis EvalAssumeCheckers.push_back(checkfn); 617312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 618312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 619e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) { 620e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis EvalCallCheckers.push_back(checkfn); 621e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} 622e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 623dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaksvoid CheckerManager::_registerForInlineCall(InlineCallFunc checkfn) { 624dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks InlineCallCheckers.push_back(checkfn); 625dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks} 626dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks 6279be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid CheckerManager::_registerForEndOfTranslationUnit( 6289be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek CheckEndOfTranslationUnit checkfn) { 6299be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek EndOfTranslationUnitCheckers.push_back(checkfn); 6309be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek} 6319be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 632769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 633769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details. 634769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 635769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 636769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::CachedStmtCheckers * 637769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) { 638769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis assert(S); 639769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 640769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersKey key(S->getStmtClass(), isPreVisit); 641769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckers *checkers = 0; 642769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CachedStmtCheckersMapTy::iterator CCI = CachedStmtCheckersMap.find(key); 643769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (CCI != CachedStmtCheckersMap.end()) { 644769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers = &(CCI->second); 645769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } else { 646769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // Find the checkers that should run for this Stmt and cache them. 647769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers = &CachedStmtCheckersMap[key]; 648769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (unsigned i = 0, e = StmtCheckers.size(); i != e; ++i) { 649769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis StmtCheckerInfo &info = StmtCheckers[i]; 650769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (info.IsPreVisit == isPreVisit && info.IsForStmtFn(S)) 651769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis checkers->push_back(info.CheckFn); 652769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 6539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 654769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 655769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis assert(checkers); 656769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return checkers; 657769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 658769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 659769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::~CheckerManager() { 660769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (unsigned i = 0, e = CheckerDtors.size(); i != e; ++i) 661769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerDtors[i](); 6629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} 6639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 66443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Anchor for the vtable. 665e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisGraphExpander::~GraphExpander() { } 666