clang API Documentation

GRState.cpp

Go to the documentation of this file.
00001 //= GRState.cpp - Path-Sensitive "State" for tracking values -----*- C++ -*--=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements GRState and GRStateManager.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Analysis/CFG.h"
00015 #include "clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h"
00016 #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
00017 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
00018 #include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h"
00019 #include "llvm/Support/raw_ostream.h"
00020 
00021 using namespace clang;
00022 using namespace ento;
00023 
00024 // Give the vtable for ConstraintManager somewhere to live.
00025 // FIXME: Move this elsewhere.
00026 ConstraintManager::~ConstraintManager() {}
00027 
00028 GRState::GRState(GRStateManager *mgr, const Environment& env,
00029                  StoreRef st, GenericDataMap gdm)
00030   : stateMgr(mgr),
00031     Env(env),
00032     store(st.getStore()),
00033     GDM(gdm),
00034     refCount(0) {
00035   stateMgr->getStoreManager().incrementReferenceCount(store);
00036 }
00037 
00038 GRState::GRState(const GRState &RHS)
00039     : llvm::FoldingSetNode(),
00040       stateMgr(RHS.stateMgr),
00041       Env(RHS.Env),
00042       store(RHS.store),
00043       GDM(RHS.GDM),
00044       refCount(0) {
00045   stateMgr->getStoreManager().incrementReferenceCount(store);
00046 }
00047 
00048 GRState::~GRState() {
00049   if (store)
00050     stateMgr->getStoreManager().decrementReferenceCount(store);
00051 }
00052 
00053 GRStateManager::~GRStateManager() {
00054   for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
00055         E=Printers.end(); I!=E; ++I)
00056     delete *I;
00057 
00058   for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
00059        I!=E; ++I)
00060     I->second.second(I->second.first);
00061 }
00062 
00063 const GRState*
00064 GRStateManager::removeDeadBindings(const GRState *state,
00065                                    const StackFrameContext *LCtx,
00066                                    SymbolReaper& SymReaper) {
00067 
00068   // This code essentially performs a "mark-and-sweep" of the VariableBindings.
00069   // The roots are any Block-level exprs and Decls that our liveness algorithm
00070   // tells us are live.  We then see what Decls they may reference, and keep
00071   // those around.  This code more than likely can be made faster, and the
00072   // frequency of which this method is called should be experimented with
00073   // for optimum performance.
00074   GRState NewState = *state;
00075 
00076   NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, state);
00077 
00078   // Clean up the store.
00079   StoreRef newStore = StoreMgr->removeDeadBindings(NewState.getStore(), LCtx,
00080                                                    SymReaper);
00081   NewState.setStore(newStore);
00082   SymReaper.setReapedStore(newStore);
00083   
00084   return getPersistentState(NewState);
00085 }
00086 
00087 const GRState *GRStateManager::MarshalState(const GRState *state,
00088                                             const StackFrameContext *InitLoc) {
00089   // make up an empty state for now.
00090   GRState State(this,
00091                 EnvMgr.getInitialEnvironment(),
00092                 StoreMgr->getInitialStore(InitLoc),
00093                 GDMFactory.getEmptyMap());
00094 
00095   return getPersistentState(State);
00096 }
00097 
00098 const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr *CL,
00099                                             const LocationContext *LC,
00100                                             SVal V) const {
00101   const StoreRef &newStore = 
00102     getStateManager().StoreMgr->BindCompoundLiteral(getStore(), CL, LC, V);
00103   return makeWithStore(newStore);
00104 }
00105 
00106 const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
00107   const StoreRef &newStore =
00108     getStateManager().StoreMgr->BindDecl(getStore(), VR, IVal);
00109   return makeWithStore(newStore);
00110 }
00111 
00112 const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
00113   const StoreRef &newStore =
00114     getStateManager().StoreMgr->BindDeclWithNoInit(getStore(), VR);
00115   return makeWithStore(newStore);
00116 }
00117 
00118 const GRState *GRState::bindLoc(Loc LV, SVal V) const {
00119   GRStateManager &Mgr = getStateManager();
00120   const GRState *newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(), 
00121                                                              LV, V));
00122   const MemRegion *MR = LV.getAsRegion();
00123   if (MR && Mgr.getOwningEngine())
00124     return Mgr.getOwningEngine()->processRegionChange(newState, MR);
00125 
00126   return newState;
00127 }
00128 
00129 const GRState *GRState::bindDefault(SVal loc, SVal V) const {
00130   GRStateManager &Mgr = getStateManager();
00131   const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
00132   const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
00133   const GRState *new_state = makeWithStore(newStore);
00134   return Mgr.getOwningEngine() ? 
00135            Mgr.getOwningEngine()->processRegionChange(new_state, R) : 
00136            new_state;
00137 }
00138 
00139 const GRState *GRState::invalidateRegions(const MemRegion * const *Begin,
00140                                           const MemRegion * const *End,
00141                                           const Expr *E, unsigned Count,
00142                                           StoreManager::InvalidatedSymbols *IS,
00143                                           bool invalidateGlobals) const {
00144   if (!IS) {
00145     StoreManager::InvalidatedSymbols invalidated;
00146     return invalidateRegionsImpl(Begin, End, E, Count,
00147                              invalidated, invalidateGlobals);
00148   }
00149   return invalidateRegionsImpl(Begin, End, E, Count, *IS, invalidateGlobals);
00150 }
00151 
00152 const GRState *
00153 GRState::invalidateRegionsImpl(const MemRegion * const *Begin,
00154                                const MemRegion * const *End,
00155                                const Expr *E, unsigned Count,
00156                                StoreManager::InvalidatedSymbols &IS,
00157                                bool invalidateGlobals) const {
00158   GRStateManager &Mgr = getStateManager();
00159   SubEngine* Eng = Mgr.getOwningEngine();
00160  
00161   if (Eng && Eng->wantsRegionChangeUpdate(this)) {
00162     StoreManager::InvalidatedRegions Regions;
00163     const StoreRef &newStore
00164       = Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS,
00165                                         invalidateGlobals, &Regions);
00166     const GRState *newState = makeWithStore(newStore);
00167     return Eng->processRegionChanges(newState, &IS,
00168                                      &Regions.front(),
00169                                      &Regions.back()+1);
00170   }
00171 
00172   const StoreRef &newStore =
00173     Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS,
00174                                     invalidateGlobals, NULL);
00175   return makeWithStore(newStore);
00176 }
00177 
00178 const GRState *GRState::unbindLoc(Loc LV) const {
00179   assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead.");
00180 
00181   Store OldStore = getStore();
00182   const StoreRef &newStore = getStateManager().StoreMgr->Remove(OldStore, LV);
00183 
00184   if (newStore.getStore() == OldStore)
00185     return this;
00186 
00187   return makeWithStore(newStore);
00188 }
00189 
00190 const GRState *GRState::enterStackFrame(const StackFrameContext *frame) const {
00191   const StoreRef &new_store =
00192     getStateManager().StoreMgr->enterStackFrame(this, frame);
00193   return makeWithStore(new_store);
00194 }
00195 
00196 SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
00197   // We only want to do fetches from regions that we can actually bind
00198   // values.  For example, SymbolicRegions of type 'id<...>' cannot
00199   // have direct bindings (but their can be bindings on their subregions).
00200   if (!R->isBoundable())
00201     return UnknownVal();
00202 
00203   if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
00204     QualType T = TR->getValueType();
00205     if (Loc::isLocType(T) || T->isIntegerType())
00206       return getSVal(R);
00207   }
00208 
00209   return UnknownVal();
00210 }
00211 
00212 SVal GRState::getSVal(Loc location, QualType T) const {
00213   SVal V = getRawSVal(cast<Loc>(location), T);
00214 
00215   // If 'V' is a symbolic value that is *perfectly* constrained to
00216   // be a constant value, use that value instead to lessen the burden
00217   // on later analysis stages (so we have less symbolic values to reason
00218   // about).
00219   if (!T.isNull()) {
00220     if (SymbolRef sym = V.getAsSymbol()) {
00221       if (const llvm::APSInt *Int = getSymVal(sym)) {
00222         // FIXME: Because we don't correctly model (yet) sign-extension
00223         // and truncation of symbolic values, we need to convert
00224         // the integer value to the correct signedness and bitwidth.
00225         //
00226         // This shows up in the following:
00227         //
00228         //   char foo();
00229         //   unsigned x = foo();
00230         //   if (x == 54)
00231         //     ...
00232         //
00233         //  The symbolic value stored to 'x' is actually the conjured
00234         //  symbol for the call to foo(); the type of that symbol is 'char',
00235         //  not unsigned.
00236         const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
00237         
00238         if (isa<Loc>(V))
00239           return loc::ConcreteInt(NewV);
00240         else
00241           return nonloc::ConcreteInt(NewV);
00242       }
00243     }
00244   }
00245   
00246   return V;
00247 }
00248 
00249 const GRState *GRState::BindExpr(const Stmt *S, SVal V, bool Invalidate) const{
00250   Environment NewEnv = getStateManager().EnvMgr.bindExpr(Env, S, V,
00251                                                          Invalidate);
00252   if (NewEnv == Env)
00253     return this;
00254 
00255   GRState NewSt = *this;
00256   NewSt.Env = NewEnv;
00257   return getStateManager().getPersistentState(NewSt);
00258 }
00259 
00260 const GRState *GRState::bindExprAndLocation(const Stmt *S, SVal location,
00261                                             SVal V) const {
00262   Environment NewEnv =
00263     getStateManager().EnvMgr.bindExprAndLocation(Env, S, location, V);
00264 
00265   if (NewEnv == Env)
00266     return this;
00267   
00268   GRState NewSt = *this;
00269   NewSt.Env = NewEnv;
00270   return getStateManager().getPersistentState(NewSt);
00271 }
00272 
00273 const GRState *GRState::assumeInBound(DefinedOrUnknownSVal Idx,
00274                                       DefinedOrUnknownSVal UpperBound,
00275                                       bool Assumption) const {
00276   if (Idx.isUnknown() || UpperBound.isUnknown())
00277     return this;
00278 
00279   // Build an expression for 0 <= Idx < UpperBound.
00280   // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed.
00281   // FIXME: This should probably be part of SValBuilder.
00282   GRStateManager &SM = getStateManager();
00283   SValBuilder &svalBuilder = SM.getSValBuilder();
00284   ASTContext &Ctx = svalBuilder.getContext();
00285 
00286   // Get the offset: the minimum value of the array index type.
00287   BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
00288   // FIXME: This should be using ValueManager::ArrayindexTy...somehow.
00289   QualType indexTy = Ctx.IntTy;
00290   nonloc::ConcreteInt Min(BVF.getMinValue(indexTy));
00291 
00292   // Adjust the index.
00293   SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
00294                                         cast<NonLoc>(Idx), Min, indexTy);
00295   if (newIdx.isUnknownOrUndef())
00296     return this;
00297 
00298   // Adjust the upper bound.
00299   SVal newBound =
00300     svalBuilder.evalBinOpNN(this, BO_Add, cast<NonLoc>(UpperBound),
00301                             Min, indexTy);
00302 
00303   if (newBound.isUnknownOrUndef())
00304     return this;
00305 
00306   // Build the actual comparison.
00307   SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT,
00308                                 cast<NonLoc>(newIdx), cast<NonLoc>(newBound),
00309                                 Ctx.IntTy);
00310   if (inBound.isUnknownOrUndef())
00311     return this;
00312 
00313   // Finally, let the constraint manager take care of it.
00314   ConstraintManager &CM = SM.getConstraintManager();
00315   return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
00316 }
00317 
00318 const GRState *GRStateManager::getInitialState(const LocationContext *InitLoc) {
00319   GRState State(this,
00320                 EnvMgr.getInitialEnvironment(),
00321                 StoreMgr->getInitialStore(InitLoc),
00322                 GDMFactory.getEmptyMap());
00323 
00324   return getPersistentState(State);
00325 }
00326 
00327 void GRStateManager::recycleUnusedStates() {
00328   for (std::vector<GRState*>::iterator i = recentlyAllocatedStates.begin(),
00329        e = recentlyAllocatedStates.end(); i != e; ++i) {
00330     GRState *state = *i;
00331     if (state->referencedByExplodedNode())
00332       continue;
00333     StateSet.RemoveNode(state);
00334     freeStates.push_back(state);
00335     state->~GRState();
00336   }
00337   recentlyAllocatedStates.clear();
00338 }
00339 
00340 const GRState *GRStateManager::getPersistentStateWithGDM(
00341                                                      const GRState *FromState,
00342                                                      const GRState *GDMState) {
00343   GRState NewState = *FromState;
00344   NewState.GDM = GDMState->GDM;
00345   return getPersistentState(NewState);
00346 }
00347 
00348 const GRState *GRStateManager::getPersistentState(GRState &State) {
00349 
00350   llvm::FoldingSetNodeID ID;
00351   State.Profile(ID);
00352   void *InsertPos;
00353 
00354   if (GRState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
00355     return I;
00356 
00357   GRState *newState = 0;
00358   if (!freeStates.empty()) {
00359     newState = freeStates.back();
00360     freeStates.pop_back();    
00361   }
00362   else {
00363     newState = (GRState*) Alloc.Allocate<GRState>();
00364   }
00365   new (newState) GRState(State);
00366   StateSet.InsertNode(newState, InsertPos);
00367   recentlyAllocatedStates.push_back(newState);
00368   return newState;
00369 }
00370 
00371 const GRState *GRState::makeWithStore(const StoreRef &store) const {
00372   GRState NewSt = *this;
00373   NewSt.setStore(store);
00374   return getStateManager().getPersistentState(NewSt);
00375 }
00376 
00377 void GRState::setStore(const StoreRef &newStore) {
00378   Store newStoreStore = newStore.getStore();
00379   if (newStoreStore)
00380     stateMgr->getStoreManager().incrementReferenceCount(newStoreStore);
00381   if (store)
00382     stateMgr->getStoreManager().decrementReferenceCount(store);
00383   store = newStoreStore;
00384 }
00385 
00386 //===----------------------------------------------------------------------===//
00387 //  State pretty-printing.
00388 //===----------------------------------------------------------------------===//
00389 
00390 static bool IsEnvLoc(const Stmt *S) {
00391   // FIXME: This is a layering violation.  Should be in environment.
00392   return (bool) (((uintptr_t) S) & 0x1);
00393 }
00394 
00395 void GRState::print(raw_ostream &Out, CFG &C, const char* nl,
00396                     const char* sep) const {
00397   // Print the store.
00398   GRStateManager &Mgr = getStateManager();
00399   Mgr.getStoreManager().print(getStore(), Out, nl, sep);
00400 
00401   // Print Subexpression bindings.
00402   bool isFirst = true;
00403 
00404   // FIXME: All environment printing should be moved inside Environment.
00405   for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
00406     if (C.isBlkExpr(I.getKey()) || IsEnvLoc(I.getKey()))
00407       continue;
00408 
00409     if (isFirst) {
00410       Out << nl << nl << "Sub-Expressions:" << nl;
00411       isFirst = false;
00412     }
00413     else { Out << nl; }
00414 
00415     Out << " (" << (void*) I.getKey() << ") ";
00416     LangOptions LO; // FIXME.
00417     I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
00418     Out << " : " << I.getData();
00419   }
00420 
00421   // Print block-expression bindings.
00422   isFirst = true;
00423 
00424   for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
00425     if (!C.isBlkExpr(I.getKey()))
00426       continue;
00427 
00428     if (isFirst) {
00429       Out << nl << nl << "Block-level Expressions:" << nl;
00430       isFirst = false;
00431     }
00432     else { Out << nl; }
00433 
00434     Out << " (" << (void*) I.getKey() << ") ";
00435     LangOptions LO; // FIXME.
00436     I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
00437     Out << " : " << I.getData();
00438   }
00439   
00440   // Print locations.
00441   isFirst = true;
00442   
00443   for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
00444     if (!IsEnvLoc(I.getKey()))
00445       continue;
00446     
00447     if (isFirst) {
00448       Out << nl << nl << "Load/store locations:" << nl;
00449       isFirst = false;
00450     }
00451     else { Out << nl; }
00452 
00453     const Stmt *S = (Stmt*) (((uintptr_t) I.getKey()) & ((uintptr_t) ~0x1));
00454     
00455     Out << " (" << (void*) S << ") ";
00456     LangOptions LO; // FIXME.
00457     S->printPretty(Out, 0, PrintingPolicy(LO));
00458     Out << " : " << I.getData();
00459   }
00460 
00461   Mgr.getConstraintManager().print(this, Out, nl, sep);
00462 
00463   // Print checker-specific data.
00464   for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(),
00465                                        E = Mgr.Printers.end(); I != E; ++I) {
00466     (*I)->Print(Out, this, nl, sep);
00467   }
00468 }
00469 
00470 void GRState::printDOT(raw_ostream &Out, CFG &C) const {
00471   print(Out, C, "\\l", "\\|");
00472 }
00473 
00474 void GRState::printStdErr(CFG &C) const {
00475   print(llvm::errs(), C);
00476 }
00477 
00478 //===----------------------------------------------------------------------===//
00479 // Generic Data Map.
00480 //===----------------------------------------------------------------------===//
00481 
00482 void *const* GRState::FindGDM(void *K) const {
00483   return GDM.lookup(K);
00484 }
00485 
00486 void*
00487 GRStateManager::FindGDMContext(void *K,
00488                                void *(*CreateContext)(llvm::BumpPtrAllocator&),
00489                                void (*DeleteContext)(void*)) {
00490 
00491   std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
00492   if (!p.first) {
00493     p.first = CreateContext(Alloc);
00494     p.second = DeleteContext;
00495   }
00496 
00497   return p.first;
00498 }
00499 
00500 const GRState *GRStateManager::addGDM(const GRState *St, void *Key, void *Data){
00501   GRState::GenericDataMap M1 = St->getGDM();
00502   GRState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data);
00503 
00504   if (M1 == M2)
00505     return St;
00506 
00507   GRState NewSt = *St;
00508   NewSt.GDM = M2;
00509   return getPersistentState(NewSt);
00510 }
00511 
00512 const GRState *GRStateManager::removeGDM(const GRState *state, void *Key) {
00513   GRState::GenericDataMap OldM = state->getGDM();
00514   GRState::GenericDataMap NewM = GDMFactory.remove(OldM, Key);
00515 
00516   if (NewM == OldM)
00517     return state;
00518 
00519   GRState NewState = *state;
00520   NewState.GDM = NewM;
00521   return getPersistentState(NewState);
00522 }
00523 
00524 //===----------------------------------------------------------------------===//
00525 // Utility.
00526 //===----------------------------------------------------------------------===//
00527 
00528 namespace {
00529 class ScanReachableSymbols : public SubRegionMap::Visitor  {
00530   typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
00531 
00532   VisitedItems visited;
00533   const GRState *state;
00534   SymbolVisitor &visitor;
00535   llvm::OwningPtr<SubRegionMap> SRM;
00536 public:
00537 
00538   ScanReachableSymbols(const GRState *st, SymbolVisitor& v)
00539     : state(st), visitor(v) {}
00540 
00541   bool scan(nonloc::CompoundVal val);
00542   bool scan(SVal val);
00543   bool scan(const MemRegion *R);
00544   bool scan(const SymExpr *sym);
00545 
00546   // From SubRegionMap::Visitor.
00547   bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
00548     return scan(SubRegion);
00549   }
00550 };
00551 }
00552 
00553 bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
00554   for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
00555     if (!scan(*I))
00556       return false;
00557 
00558   return true;
00559 }
00560 
00561 bool ScanReachableSymbols::scan(const SymExpr *sym) {
00562   unsigned &isVisited = visited[sym];
00563   if (isVisited)
00564     return true;
00565   isVisited = 1;
00566   
00567   if (const SymbolData *sData = dyn_cast<SymbolData>(sym))
00568     if (!visitor.VisitSymbol(sData))
00569       return false;
00570   
00571   switch (sym->getKind()) {
00572     case SymExpr::RegionValueKind:
00573     case SymExpr::ConjuredKind:
00574     case SymExpr::DerivedKind:
00575     case SymExpr::ExtentKind:
00576     case SymExpr::MetadataKind:
00577       break;
00578     case SymExpr::SymIntKind:
00579       return scan(cast<SymIntExpr>(sym)->getLHS());
00580     case SymExpr::SymSymKind: {
00581       const SymSymExpr *x = cast<SymSymExpr>(sym);
00582       return scan(x->getLHS()) && scan(x->getRHS());
00583     }
00584   }
00585   return true;
00586 }
00587 
00588 bool ScanReachableSymbols::scan(SVal val) {
00589   if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
00590     return scan(X->getRegion());
00591 
00592   if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val))
00593     return scan(X->getLoc());
00594 
00595   if (SymbolRef Sym = val.getAsSymbol())
00596     return scan(Sym);
00597 
00598   if (const SymExpr *Sym = val.getAsSymbolicExpression())
00599     return scan(Sym);
00600 
00601   if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
00602     return scan(*X);
00603 
00604   return true;
00605 }
00606 
00607 bool ScanReachableSymbols::scan(const MemRegion *R) {
00608   if (isa<MemSpaceRegion>(R))
00609     return true;
00610   
00611   unsigned &isVisited = visited[R];
00612   if (isVisited)
00613     return true;
00614   isVisited = 1;
00615 
00616   // If this is a symbolic region, visit the symbol for the region.
00617   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
00618     if (!visitor.VisitSymbol(SR->getSymbol()))
00619       return false;
00620 
00621   // If this is a subregion, also visit the parent regions.
00622   if (const SubRegion *SR = dyn_cast<SubRegion>(R))
00623     if (!scan(SR->getSuperRegion()))
00624       return false;
00625 
00626   // Now look at the binding to this region (if any).
00627   if (!scan(state->getSValAsScalarOrLoc(R)))
00628     return false;
00629 
00630   // Now look at the subregions.
00631   if (!SRM.get())
00632     SRM.reset(state->getStateManager().getStoreManager().
00633                                            getSubRegionMap(state->getStore()));
00634 
00635   return SRM->iterSubRegions(R, *this);
00636 }
00637 
00638 bool GRState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const {
00639   ScanReachableSymbols S(this, visitor);
00640   return S.scan(val);
00641 }
00642 
00643 bool GRState::scanReachableSymbols(const SVal *I, const SVal *E,
00644                                    SymbolVisitor &visitor) const {
00645   ScanReachableSymbols S(this, visitor);
00646   for ( ; I != E; ++I) {
00647     if (!S.scan(*I))
00648       return false;
00649   }
00650   return true;
00651 }
00652 
00653 bool GRState::scanReachableSymbols(const MemRegion * const *I,
00654                                    const MemRegion * const *E,
00655                                    SymbolVisitor &visitor) const {
00656   ScanReachableSymbols S(this, visitor);
00657   for ( ; I != E; ++I) {
00658     if (!S.scan(*I))
00659       return false;
00660   }
00661   return true;
00662 }