1 //= GRState.cpp - Path-Sensitive "State" for tracking values -----*- C++ -*--=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements GRState and GRStateManager. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Analysis/CFG.h" 15 #include "clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h" 16 #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" 17 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 18 #include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h" 19 #include "llvm/Support/raw_ostream.h" 20 21 using namespace clang; 22 using namespace ento; 23 24 // Give the vtable for ConstraintManager somewhere to live. 25 // FIXME: Move this elsewhere. 26 ConstraintManager::~ConstraintManager() {} 27 28 GRState::GRState(GRStateManager *mgr, const Environment& env, 29 StoreRef st, GenericDataMap gdm) 30 : stateMgr(mgr), 31 Env(env), 32 store(st.getStore()), 33 GDM(gdm), 34 refCount(0) { 35 stateMgr->getStoreManager().incrementReferenceCount(store); 36 } 37 38 GRState::GRState(const GRState& RHS) 39 : llvm::FoldingSetNode(), 40 stateMgr(RHS.stateMgr), 41 Env(RHS.Env), 42 store(RHS.store), 43 GDM(RHS.GDM), 44 refCount(0) { 45 stateMgr->getStoreManager().incrementReferenceCount(store); 46 } 47 48 GRState::~GRState() { 49 if (store) 50 stateMgr->getStoreManager().decrementReferenceCount(store); 51 } 52 53 GRStateManager::~GRStateManager() { 54 for (std::vector<GRState::Printer*>::iterator I=Printers.begin(), 55 E=Printers.end(); I!=E; ++I) 56 delete *I; 57 58 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end(); 59 I!=E; ++I) 60 I->second.second(I->second.first); 61 } 62 63 const GRState* 64 GRStateManager::removeDeadBindings(const GRState* state, 65 const StackFrameContext *LCtx, 66 SymbolReaper& SymReaper) { 67 68 // This code essentially performs a "mark-and-sweep" of the VariableBindings. 69 // The roots are any Block-level exprs and Decls that our liveness algorithm 70 // tells us are live. We then see what Decls they may reference, and keep 71 // those around. This code more than likely can be made faster, and the 72 // frequency of which this method is called should be experimented with 73 // for optimum performance. 74 llvm::SmallVector<const MemRegion*, 10> RegionRoots; 75 GRState NewState = *state; 76 77 NewState.Env = EnvMgr.removeDeadBindings(NewState.Env, SymReaper, 78 state, RegionRoots); 79 80 // Clean up the store. 81 NewState.setStore(StoreMgr->removeDeadBindings(NewState.getStore(), LCtx, 82 SymReaper, RegionRoots)); 83 state = getPersistentState(NewState); 84 return ConstraintMgr->removeDeadBindings(state, SymReaper); 85 } 86 87 const GRState *GRStateManager::MarshalState(const GRState *state, 88 const StackFrameContext *InitLoc) { 89 // make up an empty state for now. 90 GRState State(this, 91 EnvMgr.getInitialEnvironment(), 92 StoreMgr->getInitialStore(InitLoc), 93 GDMFactory.getEmptyMap()); 94 95 return getPersistentState(State); 96 } 97 98 const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL, 99 const LocationContext *LC, 100 SVal V) const { 101 const StoreRef &newStore = 102 getStateManager().StoreMgr->BindCompoundLiteral(getStore(), CL, LC, V); 103 return makeWithStore(newStore); 104 } 105 106 const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const { 107 const StoreRef &newStore = 108 getStateManager().StoreMgr->BindDecl(getStore(), VR, IVal); 109 return makeWithStore(newStore); 110 } 111 112 const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const { 113 const StoreRef &newStore = 114 getStateManager().StoreMgr->BindDeclWithNoInit(getStore(), VR); 115 return makeWithStore(newStore); 116 } 117 118 const GRState *GRState::bindLoc(Loc LV, SVal V) const { 119 GRStateManager &Mgr = getStateManager(); 120 const GRState *newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(), 121 LV, V)); 122 const MemRegion *MR = LV.getAsRegion(); 123 if (MR && Mgr.getOwningEngine()) 124 return Mgr.getOwningEngine()->processRegionChange(newState, MR); 125 126 return newState; 127 } 128 129 const GRState *GRState::bindDefault(SVal loc, SVal V) const { 130 GRStateManager &Mgr = getStateManager(); 131 const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion(); 132 const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V); 133 const GRState *new_state = makeWithStore(newStore); 134 return Mgr.getOwningEngine() ? 135 Mgr.getOwningEngine()->processRegionChange(new_state, R) : 136 new_state; 137 } 138 139 const GRState *GRState::invalidateRegions(const MemRegion * const *Begin, 140 const MemRegion * const *End, 141 const Expr *E, unsigned Count, 142 StoreManager::InvalidatedSymbols *IS, 143 bool invalidateGlobals) const { 144 if (!IS) { 145 StoreManager::InvalidatedSymbols invalidated; 146 return invalidateRegionsImpl(Begin, End, E, Count, 147 invalidated, invalidateGlobals); 148 } 149 return invalidateRegionsImpl(Begin, End, E, Count, *IS, invalidateGlobals); 150 } 151 152 const GRState * 153 GRState::invalidateRegionsImpl(const MemRegion * const *Begin, 154 const MemRegion * const *End, 155 const Expr *E, unsigned Count, 156 StoreManager::InvalidatedSymbols &IS, 157 bool invalidateGlobals) const { 158 GRStateManager &Mgr = getStateManager(); 159 SubEngine* Eng = Mgr.getOwningEngine(); 160 161 if (Eng && Eng->wantsRegionChangeUpdate(this)) { 162 StoreManager::InvalidatedRegions Regions; 163 const StoreRef &newStore 164 = Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS, 165 invalidateGlobals, &Regions); 166 const GRState *newState = makeWithStore(newStore); 167 return Eng->processRegionChanges(newState, &IS, 168 &Regions.front(), 169 &Regions.back()+1); 170 } 171 172 const StoreRef &newStore = 173 Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS, 174 invalidateGlobals, NULL); 175 return makeWithStore(newStore); 176 } 177 178 const GRState *GRState::unbindLoc(Loc LV) const { 179 assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead."); 180 181 Store OldStore = getStore(); 182 const StoreRef &newStore = getStateManager().StoreMgr->Remove(OldStore, LV); 183 184 if (newStore.getStore() == OldStore) 185 return this; 186 187 return makeWithStore(newStore); 188 } 189 190 const GRState *GRState::enterStackFrame(const StackFrameContext *frame) const { 191 const StoreRef &new_store = 192 getStateManager().StoreMgr->enterStackFrame(this, frame); 193 return makeWithStore(new_store); 194 } 195 196 SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const { 197 // We only want to do fetches from regions that we can actually bind 198 // values. For example, SymbolicRegions of type 'id<...>' cannot 199 // have direct bindings (but their can be bindings on their subregions). 200 if (!R->isBoundable()) 201 return UnknownVal(); 202 203 if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { 204 QualType T = TR->getValueType(); 205 if (Loc::isLocType(T) || T->isIntegerType()) 206 return getSVal(R); 207 } 208 209 return UnknownVal(); 210 } 211 212 SVal GRState::getSVal(Loc location, QualType T) const { 213 SVal V = getRawSVal(cast<Loc>(location), T); 214 215 // If 'V' is a symbolic value that is *perfectly* constrained to 216 // be a constant value, use that value instead to lessen the burden 217 // on later analysis stages (so we have less symbolic values to reason 218 // about). 219 if (!T.isNull()) { 220 if (SymbolRef sym = V.getAsSymbol()) { 221 if (const llvm::APSInt *Int = getSymVal(sym)) { 222 // FIXME: Because we don't correctly model (yet) sign-extension 223 // and truncation of symbolic values, we need to convert 224 // the integer value to the correct signedness and bitwidth. 225 // 226 // This shows up in the following: 227 // 228 // char foo(); 229 // unsigned x = foo(); 230 // if (x == 54) 231 // ... 232 // 233 // The symbolic value stored to 'x' is actually the conjured 234 // symbol for the call to foo(); the type of that symbol is 'char', 235 // not unsigned. 236 const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int); 237 238 if (isa<Loc>(V)) 239 return loc::ConcreteInt(NewV); 240 else 241 return nonloc::ConcreteInt(NewV); 242 } 243 } 244 } 245 246 return V; 247 } 248 249 const GRState *GRState::BindExpr(const Stmt* S, SVal V, bool Invalidate) const{ 250 Environment NewEnv = getStateManager().EnvMgr.bindExpr(Env, S, V, 251 Invalidate); 252 if (NewEnv == Env) 253 return this; 254 255 GRState NewSt = *this; 256 NewSt.Env = NewEnv; 257 return getStateManager().getPersistentState(NewSt); 258 } 259 260 const GRState *GRState::bindExprAndLocation(const Stmt *S, SVal location, 261 SVal V) const { 262 Environment NewEnv = 263 getStateManager().EnvMgr.bindExprAndLocation(Env, S, location, V); 264 265 if (NewEnv == Env) 266 return this; 267 268 GRState NewSt = *this; 269 NewSt.Env = NewEnv; 270 return getStateManager().getPersistentState(NewSt); 271 } 272 273 const GRState *GRState::assumeInBound(DefinedOrUnknownSVal Idx, 274 DefinedOrUnknownSVal UpperBound, 275 bool Assumption) const { 276 if (Idx.isUnknown() || UpperBound.isUnknown()) 277 return this; 278 279 // Build an expression for 0 <= Idx < UpperBound. 280 // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed. 281 // FIXME: This should probably be part of SValBuilder. 282 GRStateManager &SM = getStateManager(); 283 SValBuilder &svalBuilder = SM.getSValBuilder(); 284 ASTContext &Ctx = svalBuilder.getContext(); 285 286 // Get the offset: the minimum value of the array index type. 287 BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); 288 // FIXME: This should be using ValueManager::ArrayindexTy...somehow. 289 QualType indexTy = Ctx.IntTy; 290 nonloc::ConcreteInt Min(BVF.getMinValue(indexTy)); 291 292 // Adjust the index. 293 SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add, 294 cast<NonLoc>(Idx), Min, indexTy); 295 if (newIdx.isUnknownOrUndef()) 296 return this; 297 298 // Adjust the upper bound. 299 SVal newBound = 300 svalBuilder.evalBinOpNN(this, BO_Add, cast<NonLoc>(UpperBound), 301 Min, indexTy); 302 303 if (newBound.isUnknownOrUndef()) 304 return this; 305 306 // Build the actual comparison. 307 SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, 308 cast<NonLoc>(newIdx), cast<NonLoc>(newBound), 309 Ctx.IntTy); 310 if (inBound.isUnknownOrUndef()) 311 return this; 312 313 // Finally, let the constraint manager take care of it. 314 ConstraintManager &CM = SM.getConstraintManager(); 315 return CM.assume(this, cast<DefinedSVal>(inBound), Assumption); 316 } 317 318 const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) { 319 GRState State(this, 320 EnvMgr.getInitialEnvironment(), 321 StoreMgr->getInitialStore(InitLoc), 322 GDMFactory.getEmptyMap()); 323 324 return getPersistentState(State); 325 } 326 327 void GRStateManager::recycleUnusedStates() { 328 for (std::vector<GRState*>::iterator i = recentlyAllocatedStates.begin(), 329 e = recentlyAllocatedStates.end(); i != e; ++i) { 330 GRState *state = *i; 331 if (state->referencedByExplodedNode()) 332 continue; 333 StateSet.RemoveNode(state); 334 freeStates.push_back(state); 335 state->~GRState(); 336 } 337 recentlyAllocatedStates.clear(); 338 } 339 340 const GRState* GRStateManager::getPersistentState(GRState& State) { 341 342 llvm::FoldingSetNodeID ID; 343 State.Profile(ID); 344 void* InsertPos; 345 346 if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos)) 347 return I; 348 349 GRState *newState = 0; 350 if (!freeStates.empty()) { 351 newState = freeStates.back(); 352 freeStates.pop_back(); 353 } 354 else { 355 newState = (GRState*) Alloc.Allocate<GRState>(); 356 } 357 new (newState) GRState(State); 358 StateSet.InsertNode(newState, InsertPos); 359 recentlyAllocatedStates.push_back(newState); 360 return newState; 361 } 362 363 const GRState* GRState::makeWithStore(const StoreRef &store) const { 364 GRState NewSt = *this; 365 NewSt.setStore(store); 366 return getStateManager().getPersistentState(NewSt); 367 } 368 369 void GRState::setStore(const StoreRef &newStore) { 370 Store newStoreStore = newStore.getStore(); 371 if (newStoreStore) 372 stateMgr->getStoreManager().incrementReferenceCount(newStoreStore); 373 if (store) 374 stateMgr->getStoreManager().decrementReferenceCount(store); 375 store = newStoreStore; 376 } 377 378 //===----------------------------------------------------------------------===// 379 // State pretty-printing. 380 //===----------------------------------------------------------------------===// 381 382 static bool IsEnvLoc(const Stmt *S) { 383 // FIXME: This is a layering violation. Should be in environment. 384 return (bool) (((uintptr_t) S) & 0x1); 385 } 386 387 void GRState::print(llvm::raw_ostream& Out, CFG &C, const char* nl, 388 const char* sep) const { 389 // Print the store. 390 GRStateManager &Mgr = getStateManager(); 391 Mgr.getStoreManager().print(getStore(), Out, nl, sep); 392 393 // Print Subexpression bindings. 394 bool isFirst = true; 395 396 // FIXME: All environment printing should be moved inside Environment. 397 for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { 398 if (C.isBlkExpr(I.getKey()) || IsEnvLoc(I.getKey())) 399 continue; 400 401 if (isFirst) { 402 Out << nl << nl << "Sub-Expressions:" << nl; 403 isFirst = false; 404 } 405 else { Out << nl; } 406 407 Out << " (" << (void*) I.getKey() << ") "; 408 LangOptions LO; // FIXME. 409 I.getKey()->printPretty(Out, 0, PrintingPolicy(LO)); 410 Out << " : " << I.getData(); 411 } 412 413 // Print block-expression bindings. 414 isFirst = true; 415 416 for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { 417 if (!C.isBlkExpr(I.getKey())) 418 continue; 419 420 if (isFirst) { 421 Out << nl << nl << "Block-level Expressions:" << nl; 422 isFirst = false; 423 } 424 else { Out << nl; } 425 426 Out << " (" << (void*) I.getKey() << ") "; 427 LangOptions LO; // FIXME. 428 I.getKey()->printPretty(Out, 0, PrintingPolicy(LO)); 429 Out << " : " << I.getData(); 430 } 431 432 // Print locations. 433 isFirst = true; 434 435 for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { 436 if (!IsEnvLoc(I.getKey())) 437 continue; 438 439 if (isFirst) { 440 Out << nl << nl << "Load/store locations:" << nl; 441 isFirst = false; 442 } 443 else { Out << nl; } 444 445 const Stmt *S = (Stmt*) (((uintptr_t) I.getKey()) & ((uintptr_t) ~0x1)); 446 447 Out << " (" << (void*) S << ") "; 448 LangOptions LO; // FIXME. 449 S->printPretty(Out, 0, PrintingPolicy(LO)); 450 Out << " : " << I.getData(); 451 } 452 453 Mgr.getConstraintManager().print(this, Out, nl, sep); 454 455 // Print checker-specific data. 456 for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(), 457 E = Mgr.Printers.end(); I != E; ++I) { 458 (*I)->Print(Out, this, nl, sep); 459 } 460 } 461 462 void GRState::printDOT(llvm::raw_ostream& Out, CFG &C) const { 463 print(Out, C, "\\l", "\\|"); 464 } 465 466 void GRState::printStdErr(CFG &C) const { 467 print(llvm::errs(), C); 468 } 469 470 //===----------------------------------------------------------------------===// 471 // Generic Data Map. 472 //===----------------------------------------------------------------------===// 473 474 void* const* GRState::FindGDM(void* K) const { 475 return GDM.lookup(K); 476 } 477 478 void* 479 GRStateManager::FindGDMContext(void* K, 480 void* (*CreateContext)(llvm::BumpPtrAllocator&), 481 void (*DeleteContext)(void*)) { 482 483 std::pair<void*, void (*)(void*)>& p = GDMContexts[K]; 484 if (!p.first) { 485 p.first = CreateContext(Alloc); 486 p.second = DeleteContext; 487 } 488 489 return p.first; 490 } 491 492 const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){ 493 GRState::GenericDataMap M1 = St->getGDM(); 494 GRState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data); 495 496 if (M1 == M2) 497 return St; 498 499 GRState NewSt = *St; 500 NewSt.GDM = M2; 501 return getPersistentState(NewSt); 502 } 503 504 const GRState *GRStateManager::removeGDM(const GRState *state, void *Key) { 505 GRState::GenericDataMap OldM = state->getGDM(); 506 GRState::GenericDataMap NewM = GDMFactory.remove(OldM, Key); 507 508 if (NewM == OldM) 509 return state; 510 511 GRState NewState = *state; 512 NewState.GDM = NewM; 513 return getPersistentState(NewState); 514 } 515 516 //===----------------------------------------------------------------------===// 517 // Utility. 518 //===----------------------------------------------------------------------===// 519 520 namespace { 521 class ScanReachableSymbols : public SubRegionMap::Visitor { 522 typedef llvm::DenseSet<const MemRegion*> VisitedRegionsTy; 523 524 VisitedRegionsTy visited; 525 const GRState *state; 526 SymbolVisitor &visitor; 527 llvm::OwningPtr<SubRegionMap> SRM; 528 public: 529 530 ScanReachableSymbols(const GRState *st, SymbolVisitor& v) 531 : state(st), visitor(v) {} 532 533 bool scan(nonloc::CompoundVal val); 534 bool scan(SVal val); 535 bool scan(const MemRegion *R); 536 537 // From SubRegionMap::Visitor. 538 bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { 539 return scan(SubRegion); 540 } 541 }; 542 } 543 544 bool ScanReachableSymbols::scan(nonloc::CompoundVal val) { 545 for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I) 546 if (!scan(*I)) 547 return false; 548 549 return true; 550 } 551 552 bool ScanReachableSymbols::scan(SVal val) { 553 if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val)) 554 return scan(X->getRegion()); 555 556 if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val)) 557 return scan(X->getLoc()); 558 559 if (SymbolRef Sym = val.getAsSymbol()) 560 return visitor.VisitSymbol(Sym); 561 562 if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val)) 563 return scan(*X); 564 565 return true; 566 } 567 568 bool ScanReachableSymbols::scan(const MemRegion *R) { 569 if (isa<MemSpaceRegion>(R) || visited.count(R)) 570 return true; 571 572 visited.insert(R); 573 574 // If this is a symbolic region, visit the symbol for the region. 575 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) 576 if (!visitor.VisitSymbol(SR->getSymbol())) 577 return false; 578 579 // If this is a subregion, also visit the parent regions. 580 if (const SubRegion *SR = dyn_cast<SubRegion>(R)) 581 if (!scan(SR->getSuperRegion())) 582 return false; 583 584 // Now look at the binding to this region (if any). 585 if (!scan(state->getSValAsScalarOrLoc(R))) 586 return false; 587 588 // Now look at the subregions. 589 if (!SRM.get()) 590 SRM.reset(state->getStateManager().getStoreManager(). 591 getSubRegionMap(state->getStore())); 592 593 return SRM->iterSubRegions(R, *this); 594 } 595 596 bool GRState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const { 597 ScanReachableSymbols S(this, visitor); 598 return S.scan(val); 599 } 600 601 bool GRState::scanReachableSymbols(const SVal *I, const SVal *E, 602 SymbolVisitor &visitor) const { 603 ScanReachableSymbols S(this, visitor); 604 for ( ; I != E; ++I) { 605 if (!S.scan(*I)) 606 return false; 607 } 608 return true; 609 } 610 611 bool GRState::scanReachableSymbols(const MemRegion * const *I, 612 const MemRegion * const *E, 613 SymbolVisitor &visitor) const { 614 ScanReachableSymbols S(this, visitor); 615 for ( ; I != E; ++I) { 616 if (!S.scan(*I)) 617 return false; 618 } 619 return true; 620 } 621