CheckerManager.cpp revision f236b6503a4dbc44c1fccb8756bd57c9d0efdf05
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);
1568ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks      CheckerContext C(Bldr, Eng, Pred, L, 0);
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);
1958ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks      CheckerContext C(Bldr, Eng, Pred, L, 0);
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);
2378ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks      CheckerContext C(Bldr, Eng, Pred, L, 0);
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);
2768ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks      CheckerContext C(Bldr, Eng, Pred, L, 0);
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);
318af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks    CheckerContext C(Bldr, Eng, Pred, L, 0);
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);
341f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks      CheckerContext C(Bldr, Eng, Pred, L, 0);
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);
3858ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks      CheckerContext C(Bldr, Eng, Pred, L, 0);
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.
5038ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks        CheckerContext C(B, Eng, Pred, L, 0);
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