1 //== RegionStore.cpp - Field-sensitive store model --------------*- C++ -*--==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines a basic region store model. In this model, we do have field 10 // sensitivity. But we assume nothing about the heap shape. So recursive data 11 // structures are largely ignored. Basically we do 1-limiting analysis. 12 // Parameter pointers are assumed with no aliasing. Pointee objects of 13 // parameters are created lazily. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "clang/AST/Attr.h" 18 #include "clang/AST/CharUnits.h" 19 #include "clang/ASTMatchers/ASTMatchFinder.h" 20 #include "clang/Analysis/Analyses/LiveVariables.h" 21 #include "clang/Analysis/AnalysisDeclContext.h" 22 #include "clang/Basic/JsonSupport.h" 23 #include "clang/Basic/TargetInfo.h" 24 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 25 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 26 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 27 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 28 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 29 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 30 #include "llvm/ADT/ImmutableMap.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/Support/raw_ostream.h" 33 #include <optional> 34 #include <utility> 35 36 using namespace clang; 37 using namespace ento; 38 39 //===----------------------------------------------------------------------===// 40 // Representation of binding keys. 41 //===----------------------------------------------------------------------===// 42 43 namespace { 44 class BindingKey { 45 public: 46 enum Kind { Default = 0x0, Direct = 0x1 }; 47 private: 48 enum { Symbolic = 0x2 }; 49 50 llvm::PointerIntPair<const MemRegion *, 2> P; 51 uint64_t Data; 52 53 /// Create a key for a binding to region \p r, which has a symbolic offset 54 /// from region \p Base. 55 explicit BindingKey(const SubRegion *r, const SubRegion *Base, Kind k) 56 : P(r, k | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) { 57 assert(r && Base && "Must have known regions."); 58 assert(getConcreteOffsetRegion() == Base && "Failed to store base region"); 59 } 60 61 /// Create a key for a binding at \p offset from base region \p r. 62 explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k) 63 : P(r, k), Data(offset) { 64 assert(r && "Must have known regions."); 65 assert(getOffset() == offset && "Failed to store offset"); 66 assert((r == r->getBaseRegion() || 67 isa<ObjCIvarRegion, CXXDerivedObjectRegion>(r)) && 68 "Not a base"); 69 } 70 public: 71 72 bool isDirect() const { return P.getInt() & Direct; } 73 bool hasSymbolicOffset() const { return P.getInt() & Symbolic; } 74 75 const MemRegion *getRegion() const { return P.getPointer(); } 76 uint64_t getOffset() const { 77 assert(!hasSymbolicOffset()); 78 return Data; 79 } 80 81 const SubRegion *getConcreteOffsetRegion() const { 82 assert(hasSymbolicOffset()); 83 return reinterpret_cast<const SubRegion *>(static_cast<uintptr_t>(Data)); 84 } 85 86 const MemRegion *getBaseRegion() const { 87 if (hasSymbolicOffset()) 88 return getConcreteOffsetRegion()->getBaseRegion(); 89 return getRegion()->getBaseRegion(); 90 } 91 92 void Profile(llvm::FoldingSetNodeID& ID) const { 93 ID.AddPointer(P.getOpaqueValue()); 94 ID.AddInteger(Data); 95 } 96 97 static BindingKey Make(const MemRegion *R, Kind k); 98 99 bool operator<(const BindingKey &X) const { 100 if (P.getOpaqueValue() < X.P.getOpaqueValue()) 101 return true; 102 if (P.getOpaqueValue() > X.P.getOpaqueValue()) 103 return false; 104 return Data < X.Data; 105 } 106 107 bool operator==(const BindingKey &X) const { 108 return P.getOpaqueValue() == X.P.getOpaqueValue() && 109 Data == X.Data; 110 } 111 112 LLVM_DUMP_METHOD void dump() const; 113 }; 114 } // end anonymous namespace 115 116 BindingKey BindingKey::Make(const MemRegion *R, Kind k) { 117 const RegionOffset &RO = R->getAsOffset(); 118 if (RO.hasSymbolicOffset()) 119 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.getRegion()), k); 120 121 return BindingKey(RO.getRegion(), RO.getOffset(), k); 122 } 123 124 namespace llvm { 125 static inline raw_ostream &operator<<(raw_ostream &Out, BindingKey K) { 126 Out << "\"kind\": \"" << (K.isDirect() ? "Direct" : "Default") 127 << "\", \"offset\": "; 128 129 if (!K.hasSymbolicOffset()) 130 Out << K.getOffset(); 131 else 132 Out << "null"; 133 134 return Out; 135 } 136 137 } // namespace llvm 138 139 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 140 void BindingKey::dump() const { llvm::errs() << *this; } 141 #endif 142 143 //===----------------------------------------------------------------------===// 144 // Actual Store type. 145 //===----------------------------------------------------------------------===// 146 147 typedef llvm::ImmutableMap<BindingKey, SVal> ClusterBindings; 148 typedef llvm::ImmutableMapRef<BindingKey, SVal> ClusterBindingsRef; 149 typedef std::pair<BindingKey, SVal> BindingPair; 150 151 typedef llvm::ImmutableMap<const MemRegion *, ClusterBindings> 152 RegionBindings; 153 154 namespace { 155 class RegionBindingsRef : public llvm::ImmutableMapRef<const MemRegion *, 156 ClusterBindings> { 157 ClusterBindings::Factory *CBFactory; 158 159 // This flag indicates whether the current bindings are within the analysis 160 // that has started from main(). It affects how we perform loads from 161 // global variables that have initializers: if we have observed the 162 // program execution from the start and we know that these variables 163 // have not been overwritten yet, we can be sure that their initializers 164 // are still relevant. This flag never gets changed when the bindings are 165 // updated, so it could potentially be moved into RegionStoreManager 166 // (as if it's the same bindings but a different loading procedure) 167 // however that would have made the manager needlessly stateful. 168 bool IsMainAnalysis; 169 170 public: 171 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings> 172 ParentTy; 173 174 RegionBindingsRef(ClusterBindings::Factory &CBFactory, 175 const RegionBindings::TreeTy *T, 176 RegionBindings::TreeTy::Factory *F, 177 bool IsMainAnalysis) 178 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(T, F), 179 CBFactory(&CBFactory), IsMainAnalysis(IsMainAnalysis) {} 180 181 RegionBindingsRef(const ParentTy &P, 182 ClusterBindings::Factory &CBFactory, 183 bool IsMainAnalysis) 184 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(P), 185 CBFactory(&CBFactory), IsMainAnalysis(IsMainAnalysis) {} 186 187 RegionBindingsRef add(key_type_ref K, data_type_ref D) const { 188 return RegionBindingsRef(static_cast<const ParentTy *>(this)->add(K, D), 189 *CBFactory, IsMainAnalysis); 190 } 191 192 RegionBindingsRef remove(key_type_ref K) const { 193 return RegionBindingsRef(static_cast<const ParentTy *>(this)->remove(K), 194 *CBFactory, IsMainAnalysis); 195 } 196 197 RegionBindingsRef addBinding(BindingKey K, SVal V) const; 198 199 RegionBindingsRef addBinding(const MemRegion *R, 200 BindingKey::Kind k, SVal V) const; 201 202 const SVal *lookup(BindingKey K) const; 203 const SVal *lookup(const MemRegion *R, BindingKey::Kind k) const; 204 using llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>::lookup; 205 206 RegionBindingsRef removeBinding(BindingKey K); 207 208 RegionBindingsRef removeBinding(const MemRegion *R, 209 BindingKey::Kind k); 210 211 RegionBindingsRef removeBinding(const MemRegion *R) { 212 return removeBinding(R, BindingKey::Direct). 213 removeBinding(R, BindingKey::Default); 214 } 215 216 std::optional<SVal> getDirectBinding(const MemRegion *R) const; 217 218 /// getDefaultBinding - Returns an SVal* representing an optional default 219 /// binding associated with a region and its subregions. 220 std::optional<SVal> getDefaultBinding(const MemRegion *R) const; 221 222 /// Return the internal tree as a Store. 223 Store asStore() const { 224 llvm::PointerIntPair<Store, 1, bool> Ptr = { 225 asImmutableMap().getRootWithoutRetain(), IsMainAnalysis}; 226 return reinterpret_cast<Store>(Ptr.getOpaqueValue()); 227 } 228 229 bool isMainAnalysis() const { 230 return IsMainAnalysis; 231 } 232 233 void printJson(raw_ostream &Out, const char *NL = "\n", 234 unsigned int Space = 0, bool IsDot = false) const { 235 for (iterator I = begin(), E = end(); I != E; ++I) { 236 // TODO: We might need a .printJson for I.getKey() as well. 237 Indent(Out, Space, IsDot) 238 << "{ \"cluster\": \"" << I.getKey() << "\", \"pointer\": \"" 239 << (const void *)I.getKey() << "\", \"items\": [" << NL; 240 241 ++Space; 242 const ClusterBindings &CB = I.getData(); 243 for (ClusterBindings::iterator CI = CB.begin(), CE = CB.end(); CI != CE; 244 ++CI) { 245 Indent(Out, Space, IsDot) << "{ " << CI.getKey() << ", \"value\": "; 246 CI.getData().printJson(Out, /*AddQuotes=*/true); 247 Out << " }"; 248 if (std::next(CI) != CE) 249 Out << ','; 250 Out << NL; 251 } 252 253 --Space; 254 Indent(Out, Space, IsDot) << "]}"; 255 if (std::next(I) != E) 256 Out << ','; 257 Out << NL; 258 } 259 } 260 261 LLVM_DUMP_METHOD void dump() const { printJson(llvm::errs()); } 262 }; 263 } // end anonymous namespace 264 265 typedef const RegionBindingsRef& RegionBindingsConstRef; 266 267 std::optional<SVal> 268 RegionBindingsRef::getDirectBinding(const MemRegion *R) const { 269 const SVal *V = lookup(R, BindingKey::Direct); 270 return V ? std::optional<SVal>(*V) : std::nullopt; 271 } 272 273 std::optional<SVal> 274 RegionBindingsRef::getDefaultBinding(const MemRegion *R) const { 275 const SVal *V = lookup(R, BindingKey::Default); 276 return V ? std::optional<SVal>(*V) : std::nullopt; 277 } 278 279 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K, SVal V) const { 280 const MemRegion *Base = K.getBaseRegion(); 281 282 const ClusterBindings *ExistingCluster = lookup(Base); 283 ClusterBindings Cluster = 284 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap()); 285 286 ClusterBindings NewCluster = CBFactory->add(Cluster, K, V); 287 return add(Base, NewCluster); 288 } 289 290 291 RegionBindingsRef RegionBindingsRef::addBinding(const MemRegion *R, 292 BindingKey::Kind k, 293 SVal V) const { 294 return addBinding(BindingKey::Make(R, k), V); 295 } 296 297 const SVal *RegionBindingsRef::lookup(BindingKey K) const { 298 const ClusterBindings *Cluster = lookup(K.getBaseRegion()); 299 if (!Cluster) 300 return nullptr; 301 return Cluster->lookup(K); 302 } 303 304 const SVal *RegionBindingsRef::lookup(const MemRegion *R, 305 BindingKey::Kind k) const { 306 return lookup(BindingKey::Make(R, k)); 307 } 308 309 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) { 310 const MemRegion *Base = K.getBaseRegion(); 311 const ClusterBindings *Cluster = lookup(Base); 312 if (!Cluster) 313 return *this; 314 315 ClusterBindings NewCluster = CBFactory->remove(*Cluster, K); 316 if (NewCluster.isEmpty()) 317 return remove(Base); 318 return add(Base, NewCluster); 319 } 320 321 RegionBindingsRef RegionBindingsRef::removeBinding(const MemRegion *R, 322 BindingKey::Kind k){ 323 return removeBinding(BindingKey::Make(R, k)); 324 } 325 326 //===----------------------------------------------------------------------===// 327 // Main RegionStore logic. 328 //===----------------------------------------------------------------------===// 329 330 namespace { 331 class InvalidateRegionsWorker; 332 333 class RegionStoreManager : public StoreManager { 334 public: 335 RegionBindings::Factory RBFactory; 336 mutable ClusterBindings::Factory CBFactory; 337 338 typedef std::vector<SVal> SValListTy; 339 private: 340 typedef llvm::DenseMap<const LazyCompoundValData *, 341 SValListTy> LazyBindingsMapTy; 342 LazyBindingsMapTy LazyBindingsMap; 343 344 /// The largest number of fields a struct can have and still be 345 /// considered "small". 346 /// 347 /// This is currently used to decide whether or not it is worth "forcing" a 348 /// LazyCompoundVal on bind. 349 /// 350 /// This is controlled by 'region-store-small-struct-limit' option. 351 /// To disable all small-struct-dependent behavior, set the option to "0". 352 unsigned SmallStructLimit; 353 354 /// The largest number of element an array can have and still be 355 /// considered "small". 356 /// 357 /// This is currently used to decide whether or not it is worth "forcing" a 358 /// LazyCompoundVal on bind. 359 /// 360 /// This is controlled by 'region-store-small-struct-limit' option. 361 /// To disable all small-struct-dependent behavior, set the option to "0". 362 unsigned SmallArrayLimit; 363 364 /// A helper used to populate the work list with the given set of 365 /// regions. 366 void populateWorkList(InvalidateRegionsWorker &W, 367 ArrayRef<SVal> Values, 368 InvalidatedRegions *TopLevelRegions); 369 370 public: 371 RegionStoreManager(ProgramStateManager &mgr) 372 : StoreManager(mgr), RBFactory(mgr.getAllocator()), 373 CBFactory(mgr.getAllocator()), SmallStructLimit(0), SmallArrayLimit(0) { 374 ExprEngine &Eng = StateMgr.getOwningEngine(); 375 AnalyzerOptions &Options = Eng.getAnalysisManager().options; 376 SmallStructLimit = Options.RegionStoreSmallStructLimit; 377 SmallArrayLimit = Options.RegionStoreSmallArrayLimit; 378 } 379 380 /// setImplicitDefaultValue - Set the default binding for the provided 381 /// MemRegion to the value implicitly defined for compound literals when 382 /// the value is not specified. 383 RegionBindingsRef setImplicitDefaultValue(RegionBindingsConstRef B, 384 const MemRegion *R, QualType T); 385 386 /// ArrayToPointer - Emulates the "decay" of an array to a pointer 387 /// type. 'Array' represents the lvalue of the array being decayed 388 /// to a pointer, and the returned SVal represents the decayed 389 /// version of that lvalue (i.e., a pointer to the first element of 390 /// the array). This is called by ExprEngine when evaluating 391 /// casts from arrays to pointers. 392 SVal ArrayToPointer(Loc Array, QualType ElementTy) override; 393 394 /// Creates the Store that correctly represents memory contents before 395 /// the beginning of the analysis of the given top-level stack frame. 396 StoreRef getInitialStore(const LocationContext *InitLoc) override { 397 bool IsMainAnalysis = false; 398 if (const auto *FD = dyn_cast<FunctionDecl>(InitLoc->getDecl())) 399 IsMainAnalysis = FD->isMain() && !Ctx.getLangOpts().CPlusPlus; 400 return StoreRef(RegionBindingsRef( 401 RegionBindingsRef::ParentTy(RBFactory.getEmptyMap(), RBFactory), 402 CBFactory, IsMainAnalysis).asStore(), *this); 403 } 404 405 //===-------------------------------------------------------------------===// 406 // Binding values to regions. 407 //===-------------------------------------------------------------------===// 408 RegionBindingsRef invalidateGlobalRegion(MemRegion::Kind K, const Stmt *S, 409 unsigned Count, 410 const LocationContext *LCtx, 411 RegionBindingsRef B, 412 InvalidatedRegions *Invalidated); 413 414 StoreRef invalidateRegions(Store store, ArrayRef<SVal> Values, const Stmt *S, 415 unsigned Count, const LocationContext *LCtx, 416 const CallEvent *Call, InvalidatedSymbols &IS, 417 RegionAndSymbolInvalidationTraits &ITraits, 418 InvalidatedRegions *Invalidated, 419 InvalidatedRegions *InvalidatedTopLevel) override; 420 421 bool scanReachableSymbols(Store S, const MemRegion *R, 422 ScanReachableSymbols &Callbacks) override; 423 424 RegionBindingsRef removeSubRegionBindings(RegionBindingsConstRef B, 425 const SubRegion *R); 426 std::optional<SVal> 427 getConstantValFromConstArrayInitializer(RegionBindingsConstRef B, 428 const ElementRegion *R); 429 std::optional<SVal> 430 getSValFromInitListExpr(const InitListExpr *ILE, 431 const SmallVector<uint64_t, 2> &ConcreteOffsets, 432 QualType ElemT); 433 SVal getSValFromStringLiteral(const StringLiteral *SL, uint64_t Offset, 434 QualType ElemT); 435 436 public: // Part of public interface to class. 437 438 StoreRef Bind(Store store, Loc LV, SVal V) override { 439 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *this); 440 } 441 442 RegionBindingsRef bind(RegionBindingsConstRef B, Loc LV, SVal V); 443 444 // BindDefaultInitial is only used to initialize a region with 445 // a default value. 446 StoreRef BindDefaultInitial(Store store, const MemRegion *R, 447 SVal V) override { 448 RegionBindingsRef B = getRegionBindings(store); 449 // Use other APIs when you have to wipe the region that was initialized 450 // earlier. 451 assert(!(B.getDefaultBinding(R) || B.getDirectBinding(R)) && 452 "Double initialization!"); 453 B = B.addBinding(BindingKey::Make(R, BindingKey::Default), V); 454 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *this); 455 } 456 457 // BindDefaultZero is used for zeroing constructors that may accidentally 458 // overwrite existing bindings. 459 StoreRef BindDefaultZero(Store store, const MemRegion *R) override { 460 // FIXME: The offsets of empty bases can be tricky because of 461 // of the so called "empty base class optimization". 462 // If a base class has been optimized out 463 // we should not try to create a binding, otherwise we should. 464 // Unfortunately, at the moment ASTRecordLayout doesn't expose 465 // the actual sizes of the empty bases 466 // and trying to infer them from offsets/alignments 467 // seems to be error-prone and non-trivial because of the trailing padding. 468 // As a temporary mitigation we don't create bindings for empty bases. 469 if (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R)) 470 if (BR->getDecl()->isEmpty()) 471 return StoreRef(store, *this); 472 473 RegionBindingsRef B = getRegionBindings(store); 474 SVal V = svalBuilder.makeZeroVal(Ctx.CharTy); 475 B = removeSubRegionBindings(B, cast<SubRegion>(R)); 476 B = B.addBinding(BindingKey::Make(R, BindingKey::Default), V); 477 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *this); 478 } 479 480 /// Attempt to extract the fields of \p LCV and bind them to the struct region 481 /// \p R. 482 /// 483 /// This path is used when it seems advantageous to "force" loading the values 484 /// within a LazyCompoundVal to bind memberwise to the struct region, rather 485 /// than using a Default binding at the base of the entire region. This is a 486 /// heuristic attempting to avoid building long chains of LazyCompoundVals. 487 /// 488 /// \returns The updated store bindings, or \c std::nullopt if binding 489 /// non-lazily would be too expensive. 490 std::optional<RegionBindingsRef> 491 tryBindSmallStruct(RegionBindingsConstRef B, const TypedValueRegion *R, 492 const RecordDecl *RD, nonloc::LazyCompoundVal LCV); 493 494 /// BindStruct - Bind a compound value to a structure. 495 RegionBindingsRef bindStruct(RegionBindingsConstRef B, 496 const TypedValueRegion* R, SVal V); 497 498 /// BindVector - Bind a compound value to a vector. 499 RegionBindingsRef bindVector(RegionBindingsConstRef B, 500 const TypedValueRegion* R, SVal V); 501 502 std::optional<RegionBindingsRef> 503 tryBindSmallArray(RegionBindingsConstRef B, const TypedValueRegion *R, 504 const ArrayType *AT, nonloc::LazyCompoundVal LCV); 505 506 RegionBindingsRef bindArray(RegionBindingsConstRef B, 507 const TypedValueRegion* R, 508 SVal V); 509 510 /// Clears out all bindings in the given region and assigns a new value 511 /// as a Default binding. 512 RegionBindingsRef bindAggregate(RegionBindingsConstRef B, 513 const TypedRegion *R, 514 SVal DefaultVal); 515 516 /// Create a new store with the specified binding removed. 517 /// \param ST the original store, that is the basis for the new store. 518 /// \param L the location whose binding should be removed. 519 StoreRef killBinding(Store ST, Loc L) override; 520 521 void incrementReferenceCount(Store store) override { 522 getRegionBindings(store).manualRetain(); 523 } 524 525 /// If the StoreManager supports it, decrement the reference count of 526 /// the specified Store object. If the reference count hits 0, the memory 527 /// associated with the object is recycled. 528 void decrementReferenceCount(Store store) override { 529 getRegionBindings(store).manualRelease(); 530 } 531 532 bool includedInBindings(Store store, const MemRegion *region) const override; 533 534 /// Return the value bound to specified location in a given state. 535 /// 536 /// The high level logic for this method is this: 537 /// getBinding (L) 538 /// if L has binding 539 /// return L's binding 540 /// else if L is in killset 541 /// return unknown 542 /// else 543 /// if L is on stack or heap 544 /// return undefined 545 /// else 546 /// return symbolic 547 SVal getBinding(Store S, Loc L, QualType T) override { 548 return getBinding(getRegionBindings(S), L, T); 549 } 550 551 std::optional<SVal> getDefaultBinding(Store S, const MemRegion *R) override { 552 RegionBindingsRef B = getRegionBindings(S); 553 // Default bindings are always applied over a base region so look up the 554 // base region's default binding, otherwise the lookup will fail when R 555 // is at an offset from R->getBaseRegion(). 556 return B.getDefaultBinding(R->getBaseRegion()); 557 } 558 559 SVal getBinding(RegionBindingsConstRef B, Loc L, QualType T = QualType()); 560 561 SVal getBindingForElement(RegionBindingsConstRef B, const ElementRegion *R); 562 563 SVal getBindingForField(RegionBindingsConstRef B, const FieldRegion *R); 564 565 SVal getBindingForObjCIvar(RegionBindingsConstRef B, const ObjCIvarRegion *R); 566 567 SVal getBindingForVar(RegionBindingsConstRef B, const VarRegion *R); 568 569 SVal getBindingForLazySymbol(const TypedValueRegion *R); 570 571 SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B, 572 const TypedValueRegion *R, 573 QualType Ty); 574 575 SVal getLazyBinding(const SubRegion *LazyBindingRegion, 576 RegionBindingsRef LazyBinding); 577 578 /// Get bindings for the values in a struct and return a CompoundVal, used 579 /// when doing struct copy: 580 /// struct s x, y; 581 /// x = y; 582 /// y's value is retrieved by this method. 583 SVal getBindingForStruct(RegionBindingsConstRef B, const TypedValueRegion *R); 584 SVal getBindingForArray(RegionBindingsConstRef B, const TypedValueRegion *R); 585 NonLoc createLazyBinding(RegionBindingsConstRef B, const TypedValueRegion *R); 586 587 /// Used to lazily generate derived symbols for bindings that are defined 588 /// implicitly by default bindings in a super region. 589 /// 590 /// Note that callers may need to specially handle LazyCompoundVals, which 591 /// are returned as is in case the caller needs to treat them differently. 592 std::optional<SVal> 593 getBindingForDerivedDefaultValue(RegionBindingsConstRef B, 594 const MemRegion *superR, 595 const TypedValueRegion *R, QualType Ty); 596 597 /// Get the state and region whose binding this region \p R corresponds to. 598 /// 599 /// If there is no lazy binding for \p R, the returned value will have a null 600 /// \c second. Note that a null pointer can represents a valid Store. 601 std::pair<Store, const SubRegion *> 602 findLazyBinding(RegionBindingsConstRef B, const SubRegion *R, 603 const SubRegion *originalRegion); 604 605 /// Returns the cached set of interesting SVals contained within a lazy 606 /// binding. 607 /// 608 /// The precise value of "interesting" is determined for the purposes of 609 /// RegionStore's internal analysis. It must always contain all regions and 610 /// symbols, but may omit constants and other kinds of SVal. 611 /// 612 /// In contrast to compound values, LazyCompoundVals are also added 613 /// to the 'interesting values' list in addition to the child interesting 614 /// values. 615 const SValListTy &getInterestingValues(nonloc::LazyCompoundVal LCV); 616 617 //===------------------------------------------------------------------===// 618 // State pruning. 619 //===------------------------------------------------------------------===// 620 621 /// removeDeadBindings - Scans the RegionStore of 'state' for dead values. 622 /// It returns a new Store with these values removed. 623 StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, 624 SymbolReaper& SymReaper) override; 625 626 //===------------------------------------------------------------------===// 627 // Utility methods. 628 //===------------------------------------------------------------------===// 629 630 RegionBindingsRef getRegionBindings(Store store) const { 631 llvm::PointerIntPair<Store, 1, bool> Ptr; 632 Ptr.setFromOpaqueValue(const_cast<void *>(store)); 633 return RegionBindingsRef( 634 CBFactory, 635 static_cast<const RegionBindings::TreeTy *>(Ptr.getPointer()), 636 RBFactory.getTreeFactory(), 637 Ptr.getInt()); 638 } 639 640 void printJson(raw_ostream &Out, Store S, const char *NL = "\n", 641 unsigned int Space = 0, bool IsDot = false) const override; 642 643 void iterBindings(Store store, BindingsHandler& f) override { 644 RegionBindingsRef B = getRegionBindings(store); 645 for (const auto &[Region, Cluster] : B) { 646 for (const auto &[Key, Value] : Cluster) { 647 if (!Key.isDirect()) 648 continue; 649 if (const SubRegion *R = dyn_cast<SubRegion>(Key.getRegion())) { 650 // FIXME: Possibly incorporate the offset? 651 if (!f.HandleBinding(*this, store, R, Value)) 652 return; 653 } 654 } 655 } 656 } 657 }; 658 659 } // end anonymous namespace 660 661 //===----------------------------------------------------------------------===// 662 // RegionStore creation. 663 //===----------------------------------------------------------------------===// 664 665 std::unique_ptr<StoreManager> 666 ento::CreateRegionStoreManager(ProgramStateManager &StMgr) { 667 return std::make_unique<RegionStoreManager>(StMgr); 668 } 669 670 //===----------------------------------------------------------------------===// 671 // Region Cluster analysis. 672 //===----------------------------------------------------------------------===// 673 674 namespace { 675 /// Used to determine which global regions are automatically included in the 676 /// initial worklist of a ClusterAnalysis. 677 enum GlobalsFilterKind { 678 /// Don't include any global regions. 679 GFK_None, 680 /// Only include system globals. 681 GFK_SystemOnly, 682 /// Include all global regions. 683 GFK_All 684 }; 685 686 template <typename DERIVED> 687 class ClusterAnalysis { 688 protected: 689 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap; 690 typedef const MemRegion * WorkListElement; 691 typedef SmallVector<WorkListElement, 10> WorkList; 692 693 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited; 694 695 WorkList WL; 696 697 RegionStoreManager &RM; 698 ASTContext &Ctx; 699 SValBuilder &svalBuilder; 700 701 RegionBindingsRef B; 702 703 704 protected: 705 const ClusterBindings *getCluster(const MemRegion *R) { 706 return B.lookup(R); 707 } 708 709 /// Returns true if all clusters in the given memspace should be initially 710 /// included in the cluster analysis. Subclasses may provide their 711 /// own implementation. 712 bool includeEntireMemorySpace(const MemRegion *Base) { 713 return false; 714 } 715 716 public: 717 ClusterAnalysis(RegionStoreManager &rm, ProgramStateManager &StateMgr, 718 RegionBindingsRef b) 719 : RM(rm), Ctx(StateMgr.getContext()), 720 svalBuilder(StateMgr.getSValBuilder()), B(std::move(b)) {} 721 722 RegionBindingsRef getRegionBindings() const { return B; } 723 724 bool isVisited(const MemRegion *R) { 725 return Visited.count(getCluster(R)); 726 } 727 728 void GenerateClusters() { 729 // Scan the entire set of bindings and record the region clusters. 730 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); 731 RI != RE; ++RI){ 732 const MemRegion *Base = RI.getKey(); 733 734 const ClusterBindings &Cluster = RI.getData(); 735 assert(!Cluster.isEmpty() && "Empty clusters should be removed"); 736 static_cast<DERIVED*>(this)->VisitAddedToCluster(Base, Cluster); 737 738 // If the base's memspace should be entirely invalidated, add the cluster 739 // to the workspace up front. 740 if (static_cast<DERIVED*>(this)->includeEntireMemorySpace(Base)) 741 AddToWorkList(WorkListElement(Base), &Cluster); 742 } 743 } 744 745 bool AddToWorkList(WorkListElement E, const ClusterBindings *C) { 746 if (C && !Visited.insert(C).second) 747 return false; 748 WL.push_back(E); 749 return true; 750 } 751 752 bool AddToWorkList(const MemRegion *R) { 753 return static_cast<DERIVED*>(this)->AddToWorkList(R); 754 } 755 756 void RunWorkList() { 757 while (!WL.empty()) { 758 WorkListElement E = WL.pop_back_val(); 759 const MemRegion *BaseR = E; 760 761 static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR)); 762 } 763 } 764 765 void VisitAddedToCluster(const MemRegion *baseR, const ClusterBindings &C) {} 766 void VisitCluster(const MemRegion *baseR, const ClusterBindings *C) {} 767 768 void VisitCluster(const MemRegion *BaseR, const ClusterBindings *C, 769 bool Flag) { 770 static_cast<DERIVED*>(this)->VisitCluster(BaseR, C); 771 } 772 }; 773 } 774 775 //===----------------------------------------------------------------------===// 776 // Binding invalidation. 777 //===----------------------------------------------------------------------===// 778 779 bool RegionStoreManager::scanReachableSymbols(Store S, const MemRegion *R, 780 ScanReachableSymbols &Callbacks) { 781 assert(R == R->getBaseRegion() && "Should only be called for base regions"); 782 RegionBindingsRef B = getRegionBindings(S); 783 const ClusterBindings *Cluster = B.lookup(R); 784 785 if (!Cluster) 786 return true; 787 788 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end(); 789 RI != RE; ++RI) { 790 if (!Callbacks.scan(RI.getData())) 791 return false; 792 } 793 794 return true; 795 } 796 797 static inline bool isUnionField(const FieldRegion *FR) { 798 return FR->getDecl()->getParent()->isUnion(); 799 } 800 801 typedef SmallVector<const FieldDecl *, 8> FieldVector; 802 803 static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields) { 804 assert(K.hasSymbolicOffset() && "Not implemented for concrete offset keys"); 805 806 const MemRegion *Base = K.getConcreteOffsetRegion(); 807 const MemRegion *R = K.getRegion(); 808 809 while (R != Base) { 810 if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) 811 if (!isUnionField(FR)) 812 Fields.push_back(FR->getDecl()); 813 814 R = cast<SubRegion>(R)->getSuperRegion(); 815 } 816 } 817 818 static bool isCompatibleWithFields(BindingKey K, const FieldVector &Fields) { 819 assert(K.hasSymbolicOffset() && "Not implemented for concrete offset keys"); 820 821 if (Fields.empty()) 822 return true; 823 824 FieldVector FieldsInBindingKey; 825 getSymbolicOffsetFields(K, FieldsInBindingKey); 826 827 ptrdiff_t Delta = FieldsInBindingKey.size() - Fields.size(); 828 if (Delta >= 0) 829 return std::equal(FieldsInBindingKey.begin() + Delta, 830 FieldsInBindingKey.end(), 831 Fields.begin()); 832 else 833 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(), 834 Fields.begin() - Delta); 835 } 836 837 /// Collects all bindings in \p Cluster that may refer to bindings within 838 /// \p Top. 839 /// 840 /// Each binding is a pair whose \c first is the key (a BindingKey) and whose 841 /// \c second is the value (an SVal). 842 /// 843 /// The \p IncludeAllDefaultBindings parameter specifies whether to include 844 /// default bindings that may extend beyond \p Top itself, e.g. if \p Top is 845 /// an aggregate within a larger aggregate with a default binding. 846 static void 847 collectSubRegionBindings(SmallVectorImpl<BindingPair> &Bindings, 848 SValBuilder &SVB, const ClusterBindings &Cluster, 849 const SubRegion *Top, BindingKey TopKey, 850 bool IncludeAllDefaultBindings) { 851 FieldVector FieldsInSymbolicSubregions; 852 if (TopKey.hasSymbolicOffset()) { 853 getSymbolicOffsetFields(TopKey, FieldsInSymbolicSubregions); 854 Top = TopKey.getConcreteOffsetRegion(); 855 TopKey = BindingKey::Make(Top, BindingKey::Default); 856 } 857 858 // Find the length (in bits) of the region being invalidated. 859 uint64_t Length = UINT64_MAX; 860 SVal Extent = Top->getMemRegionManager().getStaticSize(Top, SVB); 861 if (std::optional<nonloc::ConcreteInt> ExtentCI = 862 Extent.getAs<nonloc::ConcreteInt>()) { 863 const llvm::APSInt &ExtentInt = ExtentCI->getValue(); 864 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned()); 865 // Extents are in bytes but region offsets are in bits. Be careful! 866 Length = ExtentInt.getLimitedValue() * SVB.getContext().getCharWidth(); 867 } else if (const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) { 868 if (FR->getDecl()->isBitField()) 869 Length = FR->getDecl()->getBitWidthValue(SVB.getContext()); 870 } 871 872 for (const auto &StoreEntry : Cluster) { 873 BindingKey NextKey = StoreEntry.first; 874 if (NextKey.getRegion() == TopKey.getRegion()) { 875 // FIXME: This doesn't catch the case where we're really invalidating a 876 // region with a symbolic offset. Example: 877 // R: points[i].y 878 // Next: points[0].x 879 880 if (NextKey.getOffset() > TopKey.getOffset() && 881 NextKey.getOffset() - TopKey.getOffset() < Length) { 882 // Case 1: The next binding is inside the region we're invalidating. 883 // Include it. 884 Bindings.push_back(StoreEntry); 885 886 } else if (NextKey.getOffset() == TopKey.getOffset()) { 887 // Case 2: The next binding is at the same offset as the region we're 888 // invalidating. In this case, we need to leave default bindings alone, 889 // since they may be providing a default value for a regions beyond what 890 // we're invalidating. 891 // FIXME: This is probably incorrect; consider invalidating an outer 892 // struct whose first field is bound to a LazyCompoundVal. 893 if (IncludeAllDefaultBindings || NextKey.isDirect()) 894 Bindings.push_back(StoreEntry); 895 } 896 897 } else if (NextKey.hasSymbolicOffset()) { 898 const MemRegion *Base = NextKey.getConcreteOffsetRegion(); 899 if (Top->isSubRegionOf(Base) && Top != Base) { 900 // Case 3: The next key is symbolic and we just changed something within 901 // its concrete region. We don't know if the binding is still valid, so 902 // we'll be conservative and include it. 903 if (IncludeAllDefaultBindings || NextKey.isDirect()) 904 if (isCompatibleWithFields(NextKey, FieldsInSymbolicSubregions)) 905 Bindings.push_back(StoreEntry); 906 } else if (const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) { 907 // Case 4: The next key is symbolic, but we changed a known 908 // super-region. In this case the binding is certainly included. 909 if (BaseSR->isSubRegionOf(Top)) 910 if (isCompatibleWithFields(NextKey, FieldsInSymbolicSubregions)) 911 Bindings.push_back(StoreEntry); 912 } 913 } 914 } 915 } 916 917 static void 918 collectSubRegionBindings(SmallVectorImpl<BindingPair> &Bindings, 919 SValBuilder &SVB, const ClusterBindings &Cluster, 920 const SubRegion *Top, bool IncludeAllDefaultBindings) { 921 collectSubRegionBindings(Bindings, SVB, Cluster, Top, 922 BindingKey::Make(Top, BindingKey::Default), 923 IncludeAllDefaultBindings); 924 } 925 926 RegionBindingsRef 927 RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B, 928 const SubRegion *Top) { 929 BindingKey TopKey = BindingKey::Make(Top, BindingKey::Default); 930 const MemRegion *ClusterHead = TopKey.getBaseRegion(); 931 932 if (Top == ClusterHead) { 933 // We can remove an entire cluster's bindings all in one go. 934 return B.remove(Top); 935 } 936 937 const ClusterBindings *Cluster = B.lookup(ClusterHead); 938 if (!Cluster) { 939 // If we're invalidating a region with a symbolic offset, we need to make 940 // sure we don't treat the base region as uninitialized anymore. 941 if (TopKey.hasSymbolicOffset()) { 942 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion(); 943 return B.addBinding(Concrete, BindingKey::Default, UnknownVal()); 944 } 945 return B; 946 } 947 948 SmallVector<BindingPair, 32> Bindings; 949 collectSubRegionBindings(Bindings, svalBuilder, *Cluster, Top, TopKey, 950 /*IncludeAllDefaultBindings=*/false); 951 952 ClusterBindingsRef Result(*Cluster, CBFactory); 953 for (BindingKey Key : llvm::make_first_range(Bindings)) 954 Result = Result.remove(Key); 955 956 // If we're invalidating a region with a symbolic offset, we need to make sure 957 // we don't treat the base region as uninitialized anymore. 958 // FIXME: This isn't very precise; see the example in 959 // collectSubRegionBindings. 960 if (TopKey.hasSymbolicOffset()) { 961 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion(); 962 Result = Result.add(BindingKey::Make(Concrete, BindingKey::Default), 963 UnknownVal()); 964 } 965 966 if (Result.isEmpty()) 967 return B.remove(ClusterHead); 968 return B.add(ClusterHead, Result.asImmutableMap()); 969 } 970 971 namespace { 972 class InvalidateRegionsWorker : public ClusterAnalysis<InvalidateRegionsWorker> 973 { 974 const Stmt *S; 975 unsigned Count; 976 const LocationContext *LCtx; 977 InvalidatedSymbols &IS; 978 RegionAndSymbolInvalidationTraits &ITraits; 979 StoreManager::InvalidatedRegions *Regions; 980 GlobalsFilterKind GlobalsFilter; 981 public: 982 InvalidateRegionsWorker(RegionStoreManager &rm, ProgramStateManager &stateMgr, 983 RegionBindingsRef b, const Stmt *S, unsigned count, 984 const LocationContext *lctx, InvalidatedSymbols &is, 985 RegionAndSymbolInvalidationTraits &ITraitsIn, 986 StoreManager::InvalidatedRegions *r, 987 GlobalsFilterKind GFK) 988 : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr, b), S(S), 989 Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r), 990 GlobalsFilter(GFK) {} 991 992 void VisitCluster(const MemRegion *baseR, const ClusterBindings *C); 993 void VisitBinding(SVal V); 994 995 using ClusterAnalysis::AddToWorkList; 996 997 bool AddToWorkList(const MemRegion *R); 998 999 /// Returns true if all clusters in the memory space for \p Base should be 1000 /// be invalidated. 1001 bool includeEntireMemorySpace(const MemRegion *Base); 1002 1003 /// Returns true if the memory space of the given region is one of the global 1004 /// regions specially included at the start of invalidation. 1005 bool isInitiallyIncludedGlobalRegion(const MemRegion *R); 1006 }; 1007 } 1008 1009 bool InvalidateRegionsWorker::AddToWorkList(const MemRegion *R) { 1010 bool doNotInvalidateSuperRegion = ITraits.hasTrait( 1011 R, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); 1012 const MemRegion *BaseR = doNotInvalidateSuperRegion ? R : R->getBaseRegion(); 1013 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR)); 1014 } 1015 1016 void InvalidateRegionsWorker::VisitBinding(SVal V) { 1017 // A symbol? Mark it touched by the invalidation. 1018 if (SymbolRef Sym = V.getAsSymbol()) 1019 IS.insert(Sym); 1020 1021 if (const MemRegion *R = V.getAsRegion()) { 1022 AddToWorkList(R); 1023 return; 1024 } 1025 1026 // Is it a LazyCompoundVal? All references get invalidated as well. 1027 if (std::optional<nonloc::LazyCompoundVal> LCS = 1028 V.getAs<nonloc::LazyCompoundVal>()) { 1029 1030 // `getInterestingValues()` returns SVals contained within LazyCompoundVals, 1031 // so there is no need to visit them. 1032 for (SVal V : RM.getInterestingValues(*LCS)) 1033 if (!isa<nonloc::LazyCompoundVal>(V)) 1034 VisitBinding(V); 1035 1036 return; 1037 } 1038 } 1039 1040 void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR, 1041 const ClusterBindings *C) { 1042 1043 bool PreserveRegionsContents = 1044 ITraits.hasTrait(baseR, 1045 RegionAndSymbolInvalidationTraits::TK_PreserveContents); 1046 1047 if (C) { 1048 for (SVal Val : llvm::make_second_range(*C)) 1049 VisitBinding(Val); 1050 1051 // Invalidate regions contents. 1052 if (!PreserveRegionsContents) 1053 B = B.remove(baseR); 1054 } 1055 1056 if (const auto *TO = dyn_cast<TypedValueRegion>(baseR)) { 1057 if (const auto *RD = TO->getValueType()->getAsCXXRecordDecl()) { 1058 1059 // Lambdas can affect all static local variables without explicitly 1060 // capturing those. 1061 // We invalidate all static locals referenced inside the lambda body. 1062 if (RD->isLambda() && RD->getLambdaCallOperator()->getBody()) { 1063 using namespace ast_matchers; 1064 1065 const char *DeclBind = "DeclBind"; 1066 StatementMatcher RefToStatic = stmt(hasDescendant(declRefExpr( 1067 to(varDecl(hasStaticStorageDuration()).bind(DeclBind))))); 1068 auto Matches = 1069 match(RefToStatic, *RD->getLambdaCallOperator()->getBody(), 1070 RD->getASTContext()); 1071 1072 for (BoundNodes &Match : Matches) { 1073 auto *VD = Match.getNodeAs<VarDecl>(DeclBind); 1074 const VarRegion *ToInvalidate = 1075 RM.getRegionManager().getVarRegion(VD, LCtx); 1076 AddToWorkList(ToInvalidate); 1077 } 1078 } 1079 } 1080 } 1081 1082 // BlockDataRegion? If so, invalidate captured variables that are passed 1083 // by reference. 1084 if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) { 1085 for (auto Var : BR->referenced_vars()) { 1086 const VarRegion *VR = Var.getCapturedRegion(); 1087 const VarDecl *VD = VR->getDecl(); 1088 if (VD->hasAttr<BlocksAttr>() || !VD->hasLocalStorage()) { 1089 AddToWorkList(VR); 1090 } 1091 else if (Loc::isLocType(VR->getValueType())) { 1092 // Map the current bindings to a Store to retrieve the value 1093 // of the binding. If that binding itself is a region, we should 1094 // invalidate that region. This is because a block may capture 1095 // a pointer value, but the thing pointed by that pointer may 1096 // get invalidated. 1097 SVal V = RM.getBinding(B, loc::MemRegionVal(VR)); 1098 if (std::optional<Loc> L = V.getAs<Loc>()) { 1099 if (const MemRegion *LR = L->getAsRegion()) 1100 AddToWorkList(LR); 1101 } 1102 } 1103 } 1104 return; 1105 } 1106 1107 // Symbolic region? 1108 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) 1109 IS.insert(SR->getSymbol()); 1110 1111 // Nothing else should be done in the case when we preserve regions context. 1112 if (PreserveRegionsContents) 1113 return; 1114 1115 // Otherwise, we have a normal data region. Record that we touched the region. 1116 if (Regions) 1117 Regions->push_back(baseR); 1118 1119 if (isa<AllocaRegion, SymbolicRegion>(baseR)) { 1120 // Invalidate the region by setting its default value to 1121 // conjured symbol. The type of the symbol is irrelevant. 1122 DefinedOrUnknownSVal V = 1123 svalBuilder.conjureSymbolVal(baseR, S, LCtx, Ctx.IntTy, Count); 1124 B = B.addBinding(baseR, BindingKey::Default, V); 1125 return; 1126 } 1127 1128 if (!baseR->isBoundable()) 1129 return; 1130 1131 const TypedValueRegion *TR = cast<TypedValueRegion>(baseR); 1132 QualType T = TR->getValueType(); 1133 1134 if (isInitiallyIncludedGlobalRegion(baseR)) { 1135 // If the region is a global and we are invalidating all globals, 1136 // erasing the entry is good enough. This causes all globals to be lazily 1137 // symbolicated from the same base symbol. 1138 return; 1139 } 1140 1141 if (T->isRecordType()) { 1142 // Invalidate the region by setting its default value to 1143 // conjured symbol. The type of the symbol is irrelevant. 1144 DefinedOrUnknownSVal V = 1145 svalBuilder.conjureSymbolVal(baseR, S, LCtx, Ctx.IntTy, Count); 1146 B = B.addBinding(baseR, BindingKey::Default, V); 1147 return; 1148 } 1149 1150 if (const ArrayType *AT = Ctx.getAsArrayType(T)) { 1151 bool doNotInvalidateSuperRegion = ITraits.hasTrait( 1152 baseR, 1153 RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); 1154 1155 if (doNotInvalidateSuperRegion) { 1156 // We are not doing blank invalidation of the whole array region so we 1157 // have to manually invalidate each elements. 1158 std::optional<uint64_t> NumElements; 1159 1160 // Compute lower and upper offsets for region within array. 1161 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) 1162 NumElements = CAT->getZExtSize(); 1163 if (!NumElements) // We are not dealing with a constant size array 1164 goto conjure_default; 1165 QualType ElementTy = AT->getElementType(); 1166 uint64_t ElemSize = Ctx.getTypeSize(ElementTy); 1167 const RegionOffset &RO = baseR->getAsOffset(); 1168 const MemRegion *SuperR = baseR->getBaseRegion(); 1169 if (RO.hasSymbolicOffset()) { 1170 // If base region has a symbolic offset, 1171 // we revert to invalidating the super region. 1172 if (SuperR) 1173 AddToWorkList(SuperR); 1174 goto conjure_default; 1175 } 1176 1177 uint64_t LowerOffset = RO.getOffset(); 1178 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize; 1179 bool UpperOverflow = UpperOffset < LowerOffset; 1180 1181 // Invalidate regions which are within array boundaries, 1182 // or have a symbolic offset. 1183 if (!SuperR) 1184 goto conjure_default; 1185 1186 const ClusterBindings *C = B.lookup(SuperR); 1187 if (!C) 1188 goto conjure_default; 1189 1190 for (const auto &[BK, V] : *C) { 1191 std::optional<uint64_t> ROffset = 1192 BK.hasSymbolicOffset() ? std::optional<uint64_t>() : BK.getOffset(); 1193 1194 // Check offset is not symbolic and within array's boundaries. 1195 // Handles arrays of 0 elements and of 0-sized elements as well. 1196 if (!ROffset || 1197 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) || 1198 (UpperOverflow && 1199 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) || 1200 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) { 1201 B = B.removeBinding(BK); 1202 // Bound symbolic regions need to be invalidated for dead symbol 1203 // detection. 1204 const MemRegion *R = V.getAsRegion(); 1205 if (isa_and_nonnull<SymbolicRegion>(R)) 1206 VisitBinding(V); 1207 } 1208 } 1209 } 1210 conjure_default: 1211 // Set the default value of the array to conjured symbol. 1212 DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal( 1213 baseR, S, LCtx, AT->getElementType(), Count); 1214 B = B.addBinding(baseR, BindingKey::Default, V); 1215 return; 1216 } 1217 1218 DefinedOrUnknownSVal V = 1219 svalBuilder.conjureSymbolVal(baseR, S, LCtx, T, Count); 1220 assert(SymbolManager::canSymbolicate(T) || V.isUnknown()); 1221 B = B.addBinding(baseR, BindingKey::Direct, V); 1222 } 1223 1224 bool InvalidateRegionsWorker::isInitiallyIncludedGlobalRegion( 1225 const MemRegion *R) { 1226 switch (GlobalsFilter) { 1227 case GFK_None: 1228 return false; 1229 case GFK_SystemOnly: 1230 return isa<GlobalSystemSpaceRegion>(R->getMemorySpace()); 1231 case GFK_All: 1232 return isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()); 1233 } 1234 1235 llvm_unreachable("unknown globals filter"); 1236 } 1237 1238 bool InvalidateRegionsWorker::includeEntireMemorySpace(const MemRegion *Base) { 1239 if (isInitiallyIncludedGlobalRegion(Base)) 1240 return true; 1241 1242 const MemSpaceRegion *MemSpace = Base->getMemorySpace(); 1243 return ITraits.hasTrait(MemSpace, 1244 RegionAndSymbolInvalidationTraits::TK_EntireMemSpace); 1245 } 1246 1247 RegionBindingsRef RegionStoreManager::invalidateGlobalRegion( 1248 MemRegion::Kind K, const Stmt *S, unsigned Count, 1249 const LocationContext *LCtx, RegionBindingsRef B, 1250 InvalidatedRegions *Invalidated) { 1251 // Bind the globals memory space to a new symbol that we will use to derive 1252 // the bindings for all globals. 1253 const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(K); 1254 SVal V = 1255 svalBuilder.conjureSymbolVal(/* symbolTag = */ (const void *)GS, S, LCtx, 1256 /* type does not matter */ Ctx.IntTy, Count); 1257 1258 B = B.removeBinding(GS) 1259 .addBinding(BindingKey::Make(GS, BindingKey::Default), V); 1260 1261 // Even if there are no bindings in the global scope, we still need to 1262 // record that we touched it. 1263 if (Invalidated) 1264 Invalidated->push_back(GS); 1265 1266 return B; 1267 } 1268 1269 void RegionStoreManager::populateWorkList(InvalidateRegionsWorker &W, 1270 ArrayRef<SVal> Values, 1271 InvalidatedRegions *TopLevelRegions) { 1272 for (SVal V : Values) { 1273 if (auto LCS = V.getAs<nonloc::LazyCompoundVal>()) { 1274 for (SVal S : getInterestingValues(*LCS)) 1275 if (const MemRegion *R = S.getAsRegion()) 1276 W.AddToWorkList(R); 1277 1278 continue; 1279 } 1280 1281 if (const MemRegion *R = V.getAsRegion()) { 1282 if (TopLevelRegions) 1283 TopLevelRegions->push_back(R); 1284 W.AddToWorkList(R); 1285 continue; 1286 } 1287 } 1288 } 1289 1290 StoreRef RegionStoreManager::invalidateRegions( 1291 Store store, ArrayRef<SVal> Values, const Stmt *S, unsigned Count, 1292 const LocationContext *LCtx, const CallEvent *Call, InvalidatedSymbols &IS, 1293 RegionAndSymbolInvalidationTraits &ITraits, 1294 InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) { 1295 GlobalsFilterKind GlobalsFilter; 1296 if (Call) { 1297 if (Call->isInSystemHeader()) 1298 GlobalsFilter = GFK_SystemOnly; 1299 else 1300 GlobalsFilter = GFK_All; 1301 } else { 1302 GlobalsFilter = GFK_None; 1303 } 1304 1305 RegionBindingsRef B = getRegionBindings(store); 1306 InvalidateRegionsWorker W(*this, StateMgr, B, S, Count, LCtx, IS, ITraits, 1307 Invalidated, GlobalsFilter); 1308 1309 // Scan the bindings and generate the clusters. 1310 W.GenerateClusters(); 1311 1312 // Add the regions to the worklist. 1313 populateWorkList(W, Values, TopLevelRegions); 1314 1315 W.RunWorkList(); 1316 1317 // Return the new bindings. 1318 B = W.getRegionBindings(); 1319 1320 // For calls, determine which global regions should be invalidated and 1321 // invalidate them. (Note that function-static and immutable globals are never 1322 // invalidated by this.) 1323 // TODO: This could possibly be more precise with modules. 1324 switch (GlobalsFilter) { 1325 case GFK_All: 1326 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind, S, 1327 Count, LCtx, B, Invalidated); 1328 [[fallthrough]]; 1329 case GFK_SystemOnly: 1330 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind, S, Count, 1331 LCtx, B, Invalidated); 1332 [[fallthrough]]; 1333 case GFK_None: 1334 break; 1335 } 1336 1337 return StoreRef(B.asStore(), *this); 1338 } 1339 1340 //===----------------------------------------------------------------------===// 1341 // Location and region casting. 1342 //===----------------------------------------------------------------------===// 1343 1344 /// ArrayToPointer - Emulates the "decay" of an array to a pointer 1345 /// type. 'Array' represents the lvalue of the array being decayed 1346 /// to a pointer, and the returned SVal represents the decayed 1347 /// version of that lvalue (i.e., a pointer to the first element of 1348 /// the array). This is called by ExprEngine when evaluating casts 1349 /// from arrays to pointers. 1350 SVal RegionStoreManager::ArrayToPointer(Loc Array, QualType T) { 1351 if (isa<loc::ConcreteInt>(Array)) 1352 return Array; 1353 1354 if (!isa<loc::MemRegionVal>(Array)) 1355 return UnknownVal(); 1356 1357 const SubRegion *R = 1358 cast<SubRegion>(Array.castAs<loc::MemRegionVal>().getRegion()); 1359 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex(); 1360 return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx)); 1361 } 1362 1363 //===----------------------------------------------------------------------===// 1364 // Loading values from regions. 1365 //===----------------------------------------------------------------------===// 1366 1367 SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) { 1368 assert(!isa<UnknownVal>(L) && "location unknown"); 1369 assert(!isa<UndefinedVal>(L) && "location undefined"); 1370 1371 // For access to concrete addresses, return UnknownVal. Checks 1372 // for null dereferences (and similar errors) are done by checkers, not 1373 // the Store. 1374 // FIXME: We can consider lazily symbolicating such memory, but we really 1375 // should defer this when we can reason easily about symbolicating arrays 1376 // of bytes. 1377 if (L.getAs<loc::ConcreteInt>()) { 1378 return UnknownVal(); 1379 } 1380 if (!L.getAs<loc::MemRegionVal>()) { 1381 return UnknownVal(); 1382 } 1383 1384 const MemRegion *MR = L.castAs<loc::MemRegionVal>().getRegion(); 1385 1386 if (isa<BlockDataRegion>(MR)) { 1387 return UnknownVal(); 1388 } 1389 1390 // Auto-detect the binding type. 1391 if (T.isNull()) { 1392 if (const auto *TVR = dyn_cast<TypedValueRegion>(MR)) 1393 T = TVR->getValueType(); 1394 else if (const auto *TR = dyn_cast<TypedRegion>(MR)) 1395 T = TR->getLocationType()->getPointeeType(); 1396 else if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) 1397 T = SR->getPointeeStaticType(); 1398 } 1399 assert(!T.isNull() && "Unable to auto-detect binding type!"); 1400 assert(!T->isVoidType() && "Attempting to dereference a void pointer!"); 1401 1402 if (!isa<TypedValueRegion>(MR)) 1403 MR = GetElementZeroRegion(cast<SubRegion>(MR), T); 1404 1405 // FIXME: Perhaps this method should just take a 'const MemRegion*' argument 1406 // instead of 'Loc', and have the other Loc cases handled at a higher level. 1407 const TypedValueRegion *R = cast<TypedValueRegion>(MR); 1408 QualType RTy = R->getValueType(); 1409 1410 // FIXME: we do not yet model the parts of a complex type, so treat the 1411 // whole thing as "unknown". 1412 if (RTy->isAnyComplexType()) 1413 return UnknownVal(); 1414 1415 // FIXME: We should eventually handle funny addressing. e.g.: 1416 // 1417 // int x = ...; 1418 // int *p = &x; 1419 // char *q = (char*) p; 1420 // char c = *q; // returns the first byte of 'x'. 1421 // 1422 // Such funny addressing will occur due to layering of regions. 1423 if (RTy->isStructureOrClassType()) 1424 return getBindingForStruct(B, R); 1425 1426 // FIXME: Handle unions. 1427 if (RTy->isUnionType()) 1428 return createLazyBinding(B, R); 1429 1430 if (RTy->isArrayType()) { 1431 if (RTy->isConstantArrayType()) 1432 return getBindingForArray(B, R); 1433 else 1434 return UnknownVal(); 1435 } 1436 1437 // FIXME: handle Vector types. 1438 if (RTy->isVectorType()) 1439 return UnknownVal(); 1440 1441 if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) 1442 return svalBuilder.evalCast(getBindingForField(B, FR), T, QualType{}); 1443 1444 if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) { 1445 // FIXME: Here we actually perform an implicit conversion from the loaded 1446 // value to the element type. Eventually we want to compose these values 1447 // more intelligently. For example, an 'element' can encompass multiple 1448 // bound regions (e.g., several bound bytes), or could be a subset of 1449 // a larger value. 1450 return svalBuilder.evalCast(getBindingForElement(B, ER), T, QualType{}); 1451 } 1452 1453 if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) { 1454 // FIXME: Here we actually perform an implicit conversion from the loaded 1455 // value to the ivar type. What we should model is stores to ivars 1456 // that blow past the extent of the ivar. If the address of the ivar is 1457 // reinterpretted, it is possible we stored a different value that could 1458 // fit within the ivar. Either we need to cast these when storing them 1459 // or reinterpret them lazily (as we do here). 1460 return svalBuilder.evalCast(getBindingForObjCIvar(B, IVR), T, QualType{}); 1461 } 1462 1463 if (const VarRegion *VR = dyn_cast<VarRegion>(R)) { 1464 // FIXME: Here we actually perform an implicit conversion from the loaded 1465 // value to the variable type. What we should model is stores to variables 1466 // that blow past the extent of the variable. If the address of the 1467 // variable is reinterpretted, it is possible we stored a different value 1468 // that could fit within the variable. Either we need to cast these when 1469 // storing them or reinterpret them lazily (as we do here). 1470 return svalBuilder.evalCast(getBindingForVar(B, VR), T, QualType{}); 1471 } 1472 1473 const SVal *V = B.lookup(R, BindingKey::Direct); 1474 1475 // Check if the region has a binding. 1476 if (V) 1477 return *V; 1478 1479 // The location does not have a bound value. This means that it has 1480 // the value it had upon its creation and/or entry to the analyzed 1481 // function/method. These are either symbolic values or 'undefined'. 1482 if (R->hasStackNonParametersStorage()) { 1483 // All stack variables are considered to have undefined values 1484 // upon creation. All heap allocated blocks are considered to 1485 // have undefined values as well unless they are explicitly bound 1486 // to specific values. 1487 return UndefinedVal(); 1488 } 1489 1490 // All other values are symbolic. 1491 return svalBuilder.getRegionValueSymbolVal(R); 1492 } 1493 1494 static QualType getUnderlyingType(const SubRegion *R) { 1495 QualType RegionTy; 1496 if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) 1497 RegionTy = TVR->getValueType(); 1498 1499 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) 1500 RegionTy = SR->getSymbol()->getType(); 1501 1502 return RegionTy; 1503 } 1504 1505 /// Checks to see if store \p B has a lazy binding for region \p R. 1506 /// 1507 /// If \p AllowSubregionBindings is \c false, a lazy binding will be rejected 1508 /// if there are additional bindings within \p R. 1509 /// 1510 /// Note that unlike RegionStoreManager::findLazyBinding, this will not search 1511 /// for lazy bindings for super-regions of \p R. 1512 static std::optional<nonloc::LazyCompoundVal> 1513 getExistingLazyBinding(SValBuilder &SVB, RegionBindingsConstRef B, 1514 const SubRegion *R, bool AllowSubregionBindings) { 1515 std::optional<SVal> V = B.getDefaultBinding(R); 1516 if (!V) 1517 return std::nullopt; 1518 1519 std::optional<nonloc::LazyCompoundVal> LCV = 1520 V->getAs<nonloc::LazyCompoundVal>(); 1521 if (!LCV) 1522 return std::nullopt; 1523 1524 // If the LCV is for a subregion, the types might not match, and we shouldn't 1525 // reuse the binding. 1526 QualType RegionTy = getUnderlyingType(R); 1527 if (!RegionTy.isNull() && 1528 !RegionTy->isVoidPointerType()) { 1529 QualType SourceRegionTy = LCV->getRegion()->getValueType(); 1530 if (!SVB.getContext().hasSameUnqualifiedType(RegionTy, SourceRegionTy)) 1531 return std::nullopt; 1532 } 1533 1534 if (!AllowSubregionBindings) { 1535 // If there are any other bindings within this region, we shouldn't reuse 1536 // the top-level binding. 1537 SmallVector<BindingPair, 16> Bindings; 1538 collectSubRegionBindings(Bindings, SVB, *B.lookup(R->getBaseRegion()), R, 1539 /*IncludeAllDefaultBindings=*/true); 1540 if (Bindings.size() > 1) 1541 return std::nullopt; 1542 } 1543 1544 return *LCV; 1545 } 1546 1547 std::pair<Store, const SubRegion *> 1548 RegionStoreManager::findLazyBinding(RegionBindingsConstRef B, 1549 const SubRegion *R, 1550 const SubRegion *originalRegion) { 1551 if (originalRegion != R) { 1552 if (std::optional<nonloc::LazyCompoundVal> V = 1553 getExistingLazyBinding(svalBuilder, B, R, true)) 1554 return std::make_pair(V->getStore(), V->getRegion()); 1555 } 1556 1557 typedef std::pair<Store, const SubRegion *> StoreRegionPair; 1558 StoreRegionPair Result = StoreRegionPair(); 1559 1560 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 1561 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()), 1562 originalRegion); 1563 1564 if (Result.second) 1565 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second); 1566 1567 } else if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) { 1568 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()), 1569 originalRegion); 1570 1571 if (Result.second) 1572 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second); 1573 1574 } else if (const CXXBaseObjectRegion *BaseReg = 1575 dyn_cast<CXXBaseObjectRegion>(R)) { 1576 // C++ base object region is another kind of region that we should blast 1577 // through to look for lazy compound value. It is like a field region. 1578 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()), 1579 originalRegion); 1580 1581 if (Result.second) 1582 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg, 1583 Result.second); 1584 } 1585 1586 return Result; 1587 } 1588 1589 /// This is a helper function for `getConstantValFromConstArrayInitializer`. 1590 /// 1591 /// Return an array of extents of the declared array type. 1592 /// 1593 /// E.g. for `int x[1][2][3];` returns { 1, 2, 3 }. 1594 static SmallVector<uint64_t, 2> 1595 getConstantArrayExtents(const ConstantArrayType *CAT) { 1596 assert(CAT && "ConstantArrayType should not be null"); 1597 CAT = cast<ConstantArrayType>(CAT->getCanonicalTypeInternal()); 1598 SmallVector<uint64_t, 2> Extents; 1599 do { 1600 Extents.push_back(CAT->getZExtSize()); 1601 } while ((CAT = dyn_cast<ConstantArrayType>(CAT->getElementType()))); 1602 return Extents; 1603 } 1604 1605 /// This is a helper function for `getConstantValFromConstArrayInitializer`. 1606 /// 1607 /// Return an array of offsets from nested ElementRegions and a root base 1608 /// region. The array is never empty and a base region is never null. 1609 /// 1610 /// E.g. for `Element{Element{Element{VarRegion},1},2},3}` returns { 3, 2, 1 }. 1611 /// This represents an access through indirection: `arr[1][2][3];` 1612 /// 1613 /// \param ER The given (possibly nested) ElementRegion. 1614 /// 1615 /// \note The result array is in the reverse order of indirection expression: 1616 /// arr[1][2][3] -> { 3, 2, 1 }. This helps to provide complexity O(n), where n 1617 /// is a number of indirections. It may not affect performance in real-life 1618 /// code, though. 1619 static std::pair<SmallVector<SVal, 2>, const MemRegion *> 1620 getElementRegionOffsetsWithBase(const ElementRegion *ER) { 1621 assert(ER && "ConstantArrayType should not be null"); 1622 const MemRegion *Base; 1623 SmallVector<SVal, 2> SValOffsets; 1624 do { 1625 SValOffsets.push_back(ER->getIndex()); 1626 Base = ER->getSuperRegion(); 1627 ER = dyn_cast<ElementRegion>(Base); 1628 } while (ER); 1629 return {SValOffsets, Base}; 1630 } 1631 1632 /// This is a helper function for `getConstantValFromConstArrayInitializer`. 1633 /// 1634 /// Convert array of offsets from `SVal` to `uint64_t` in consideration of 1635 /// respective array extents. 1636 /// \param SrcOffsets [in] The array of offsets of type `SVal` in reversed 1637 /// order (expectedly received from `getElementRegionOffsetsWithBase`). 1638 /// \param ArrayExtents [in] The array of extents. 1639 /// \param DstOffsets [out] The array of offsets of type `uint64_t`. 1640 /// \returns: 1641 /// - `std::nullopt` for successful convertion. 1642 /// - `UndefinedVal` or `UnknownVal` otherwise. It's expected that this SVal 1643 /// will be returned as a suitable value of the access operation. 1644 /// which should be returned as a correct 1645 /// 1646 /// \example: 1647 /// const int arr[10][20][30] = {}; // ArrayExtents { 10, 20, 30 } 1648 /// int x1 = arr[4][5][6]; // SrcOffsets { NonLoc(6), NonLoc(5), NonLoc(4) } 1649 /// // DstOffsets { 4, 5, 6 } 1650 /// // returns std::nullopt 1651 /// int x2 = arr[42][5][-6]; // returns UndefinedVal 1652 /// int x3 = arr[4][5][x2]; // returns UnknownVal 1653 static std::optional<SVal> 1654 convertOffsetsFromSvalToUnsigneds(const SmallVector<SVal, 2> &SrcOffsets, 1655 const SmallVector<uint64_t, 2> ArrayExtents, 1656 SmallVector<uint64_t, 2> &DstOffsets) { 1657 // Check offsets for being out of bounds. 1658 // C++20 [expr.add] 7.6.6.4 (excerpt): 1659 // If P points to an array element i of an array object x with n 1660 // elements, where i < 0 or i > n, the behavior is undefined. 1661 // Dereferencing is not allowed on the "one past the last 1662 // element", when i == n. 1663 // Example: 1664 // const int arr[3][2] = {{1, 2}, {3, 4}}; 1665 // arr[0][0]; // 1 1666 // arr[0][1]; // 2 1667 // arr[0][2]; // UB 1668 // arr[1][0]; // 3 1669 // arr[1][1]; // 4 1670 // arr[1][-1]; // UB 1671 // arr[2][0]; // 0 1672 // arr[2][1]; // 0 1673 // arr[-2][0]; // UB 1674 DstOffsets.resize(SrcOffsets.size()); 1675 auto ExtentIt = ArrayExtents.begin(); 1676 auto OffsetIt = DstOffsets.begin(); 1677 // Reverse `SValOffsets` to make it consistent with `ArrayExtents`. 1678 for (SVal V : llvm::reverse(SrcOffsets)) { 1679 if (auto CI = V.getAs<nonloc::ConcreteInt>()) { 1680 // When offset is out of array's bounds, result is UB. 1681 const llvm::APSInt &Offset = CI->getValue(); 1682 if (Offset.isNegative() || Offset.uge(*(ExtentIt++))) 1683 return UndefinedVal(); 1684 // Store index in a reversive order. 1685 *(OffsetIt++) = Offset.getZExtValue(); 1686 continue; 1687 } 1688 // Symbolic index presented. Return Unknown value. 1689 // FIXME: We also need to take ElementRegions with symbolic indexes into 1690 // account. 1691 return UnknownVal(); 1692 } 1693 return std::nullopt; 1694 } 1695 1696 std::optional<SVal> RegionStoreManager::getConstantValFromConstArrayInitializer( 1697 RegionBindingsConstRef B, const ElementRegion *R) { 1698 assert(R && "ElementRegion should not be null"); 1699 1700 // Treat an n-dimensional array. 1701 SmallVector<SVal, 2> SValOffsets; 1702 const MemRegion *Base; 1703 std::tie(SValOffsets, Base) = getElementRegionOffsetsWithBase(R); 1704 const VarRegion *VR = dyn_cast<VarRegion>(Base); 1705 if (!VR) 1706 return std::nullopt; 1707 1708 assert(!SValOffsets.empty() && "getElementRegionOffsets guarantees the " 1709 "offsets vector is not empty."); 1710 1711 // Check if the containing array has an initialized value that we can trust. 1712 // We can trust a const value or a value of a global initializer in main(). 1713 const VarDecl *VD = VR->getDecl(); 1714 if (!VD->getType().isConstQualified() && 1715 !R->getElementType().isConstQualified() && 1716 (!B.isMainAnalysis() || !VD->hasGlobalStorage())) 1717 return std::nullopt; 1718 1719 // Array's declaration should have `ConstantArrayType` type, because only this 1720 // type contains an array extent. It may happen that array type can be of 1721 // `IncompleteArrayType` type. To get the declaration of `ConstantArrayType` 1722 // type, we should find the declaration in the redeclarations chain that has 1723 // the initialization expression. 1724 // NOTE: `getAnyInitializer` has an out-parameter, which returns a new `VD` 1725 // from which an initializer is obtained. We replace current `VD` with the new 1726 // `VD`. If the return value of the function is null than `VD` won't be 1727 // replaced. 1728 const Expr *Init = VD->getAnyInitializer(VD); 1729 // NOTE: If `Init` is non-null, then a new `VD` is non-null for sure. So check 1730 // `Init` for null only and don't worry about the replaced `VD`. 1731 if (!Init) 1732 return std::nullopt; 1733 1734 // Array's declaration should have ConstantArrayType type, because only this 1735 // type contains an array extent. 1736 const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(VD->getType()); 1737 if (!CAT) 1738 return std::nullopt; 1739 1740 // Get array extents. 1741 SmallVector<uint64_t, 2> Extents = getConstantArrayExtents(CAT); 1742 1743 // The number of offsets should equal to the numbers of extents, 1744 // otherwise wrong type punning occurred. For instance: 1745 // int arr[1][2][3]; 1746 // auto ptr = (int(*)[42])arr; 1747 // auto x = ptr[4][2]; // UB 1748 // FIXME: Should return UndefinedVal. 1749 if (SValOffsets.size() != Extents.size()) 1750 return std::nullopt; 1751 1752 SmallVector<uint64_t, 2> ConcreteOffsets; 1753 if (std::optional<SVal> V = convertOffsetsFromSvalToUnsigneds( 1754 SValOffsets, Extents, ConcreteOffsets)) 1755 return *V; 1756 1757 // Handle InitListExpr. 1758 // Example: 1759 // const char arr[4][2] = { { 1, 2 }, { 3 }, 4, 5 }; 1760 if (const auto *ILE = dyn_cast<InitListExpr>(Init)) 1761 return getSValFromInitListExpr(ILE, ConcreteOffsets, R->getElementType()); 1762 1763 // Handle StringLiteral. 1764 // Example: 1765 // const char arr[] = "abc"; 1766 if (const auto *SL = dyn_cast<StringLiteral>(Init)) 1767 return getSValFromStringLiteral(SL, ConcreteOffsets.front(), 1768 R->getElementType()); 1769 1770 // FIXME: Handle CompoundLiteralExpr. 1771 1772 return std::nullopt; 1773 } 1774 1775 /// Returns an SVal, if possible, for the specified position of an 1776 /// initialization list. 1777 /// 1778 /// \param ILE The given initialization list. 1779 /// \param Offsets The array of unsigned offsets. E.g. for the expression 1780 /// `int x = arr[1][2][3];` an array should be { 1, 2, 3 }. 1781 /// \param ElemT The type of the result SVal expression. 1782 /// \return Optional SVal for the particular position in the initialization 1783 /// list. E.g. for the list `{{1, 2},[3, 4],{5, 6}, {}}` offsets: 1784 /// - {1, 1} returns SVal{4}, because it's the second position in the second 1785 /// sublist; 1786 /// - {3, 0} returns SVal{0}, because there's no explicit value at this 1787 /// position in the sublist. 1788 /// 1789 /// NOTE: Inorder to get a valid SVal, a caller shall guarantee valid offsets 1790 /// for the given initialization list. Otherwise SVal can be an equivalent to 0 1791 /// or lead to assertion. 1792 std::optional<SVal> RegionStoreManager::getSValFromInitListExpr( 1793 const InitListExpr *ILE, const SmallVector<uint64_t, 2> &Offsets, 1794 QualType ElemT) { 1795 assert(ILE && "InitListExpr should not be null"); 1796 1797 for (uint64_t Offset : Offsets) { 1798 // C++20 [dcl.init.string] 9.4.2.1: 1799 // An array of ordinary character type [...] can be initialized by [...] 1800 // an appropriately-typed string-literal enclosed in braces. 1801 // Example: 1802 // const char arr[] = { "abc" }; 1803 if (ILE->isStringLiteralInit()) 1804 if (const auto *SL = dyn_cast<StringLiteral>(ILE->getInit(0))) 1805 return getSValFromStringLiteral(SL, Offset, ElemT); 1806 1807 // C++20 [expr.add] 9.4.17.5 (excerpt): 1808 // i-th array element is value-initialized for each k < i ≤ n, 1809 // where k is an expression-list size and n is an array extent. 1810 if (Offset >= ILE->getNumInits()) 1811 return svalBuilder.makeZeroVal(ElemT); 1812 1813 const Expr *E = ILE->getInit(Offset); 1814 const auto *IL = dyn_cast<InitListExpr>(E); 1815 if (!IL) 1816 // Return a constant value, if it is presented. 1817 // FIXME: Support other SVals. 1818 return svalBuilder.getConstantVal(E); 1819 1820 // Go to the nested initializer list. 1821 ILE = IL; 1822 } 1823 1824 assert(ILE); 1825 1826 // FIXME: Unhandeled InitListExpr sub-expression, possibly constructing an 1827 // enum? 1828 return std::nullopt; 1829 } 1830 1831 /// Returns an SVal, if possible, for the specified position in a string 1832 /// literal. 1833 /// 1834 /// \param SL The given string literal. 1835 /// \param Offset The unsigned offset. E.g. for the expression 1836 /// `char x = str[42];` an offset should be 42. 1837 /// E.g. for the string "abc" offset: 1838 /// - 1 returns SVal{b}, because it's the second position in the string. 1839 /// - 42 returns SVal{0}, because there's no explicit value at this 1840 /// position in the string. 1841 /// \param ElemT The type of the result SVal expression. 1842 /// 1843 /// NOTE: We return `0` for every offset >= the literal length for array 1844 /// declarations, like: 1845 /// const char str[42] = "123"; // Literal length is 4. 1846 /// char c = str[41]; // Offset is 41. 1847 /// FIXME: Nevertheless, we can't do the same for pointer declaraions, like: 1848 /// const char * const str = "123"; // Literal length is 4. 1849 /// char c = str[41]; // Offset is 41. Returns `0`, but Undef 1850 /// // expected. 1851 /// It should be properly handled before reaching this point. 1852 /// The main problem is that we can't distinguish between these declarations, 1853 /// because in case of array we can get the Decl from VarRegion, but in case 1854 /// of pointer the region is a StringRegion, which doesn't contain a Decl. 1855 /// Possible solution could be passing an array extent along with the offset. 1856 SVal RegionStoreManager::getSValFromStringLiteral(const StringLiteral *SL, 1857 uint64_t Offset, 1858 QualType ElemT) { 1859 assert(SL && "StringLiteral should not be null"); 1860 // C++20 [dcl.init.string] 9.4.2.3: 1861 // If there are fewer initializers than there are array elements, each 1862 // element not explicitly initialized shall be zero-initialized [dcl.init]. 1863 uint32_t Code = (Offset >= SL->getLength()) ? 0 : SL->getCodeUnit(Offset); 1864 return svalBuilder.makeIntVal(Code, ElemT); 1865 } 1866 1867 static std::optional<SVal> getDerivedSymbolForBinding( 1868 RegionBindingsConstRef B, const TypedValueRegion *BaseRegion, 1869 const TypedValueRegion *SubReg, const ASTContext &Ctx, SValBuilder &SVB) { 1870 assert(BaseRegion); 1871 QualType BaseTy = BaseRegion->getValueType(); 1872 QualType Ty = SubReg->getValueType(); 1873 if (BaseTy->isScalarType() && Ty->isScalarType()) { 1874 if (Ctx.getTypeSizeInChars(BaseTy) >= Ctx.getTypeSizeInChars(Ty)) { 1875 if (const std::optional<SVal> &ParentValue = 1876 B.getDirectBinding(BaseRegion)) { 1877 if (SymbolRef ParentValueAsSym = ParentValue->getAsSymbol()) 1878 return SVB.getDerivedRegionValueSymbolVal(ParentValueAsSym, SubReg); 1879 1880 if (ParentValue->isUndef()) 1881 return UndefinedVal(); 1882 1883 // Other cases: give up. We are indexing into a larger object 1884 // that has some value, but we don't know how to handle that yet. 1885 return UnknownVal(); 1886 } 1887 } 1888 } 1889 return std::nullopt; 1890 } 1891 1892 SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B, 1893 const ElementRegion* R) { 1894 // Check if the region has a binding. 1895 if (const std::optional<SVal> &V = B.getDirectBinding(R)) 1896 return *V; 1897 1898 const MemRegion* superR = R->getSuperRegion(); 1899 1900 // Check if the region is an element region of a string literal. 1901 if (const StringRegion *StrR = dyn_cast<StringRegion>(superR)) { 1902 // FIXME: Handle loads from strings where the literal is treated as 1903 // an integer, e.g., *((unsigned int*)"hello"). Such loads are UB according 1904 // to C++20 7.2.1.11 [basic.lval]. 1905 QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType(); 1906 if (!Ctx.hasSameUnqualifiedType(T, R->getElementType())) 1907 return UnknownVal(); 1908 if (const auto CI = R->getIndex().getAs<nonloc::ConcreteInt>()) { 1909 const llvm::APSInt &Idx = CI->getValue(); 1910 if (Idx < 0) 1911 return UndefinedVal(); 1912 const StringLiteral *SL = StrR->getStringLiteral(); 1913 return getSValFromStringLiteral(SL, Idx.getZExtValue(), T); 1914 } 1915 } else if (isa<ElementRegion, VarRegion>(superR)) { 1916 if (std::optional<SVal> V = getConstantValFromConstArrayInitializer(B, R)) 1917 return *V; 1918 } 1919 1920 // Check for loads from a code text region. For such loads, just give up. 1921 if (isa<CodeTextRegion>(superR)) 1922 return UnknownVal(); 1923 1924 // Handle the case where we are indexing into a larger scalar object. 1925 // For example, this handles: 1926 // int x = ... 1927 // char *y = &x; 1928 // return *y; 1929 // FIXME: This is a hack, and doesn't do anything really intelligent yet. 1930 const RegionRawOffset &O = R->getAsArrayOffset(); 1931 1932 // If we cannot reason about the offset, return an unknown value. 1933 if (!O.getRegion()) 1934 return UnknownVal(); 1935 1936 if (const TypedValueRegion *baseR = dyn_cast<TypedValueRegion>(O.getRegion())) 1937 if (auto V = getDerivedSymbolForBinding(B, baseR, R, Ctx, svalBuilder)) 1938 return *V; 1939 1940 return getBindingForFieldOrElementCommon(B, R, R->getElementType()); 1941 } 1942 1943 SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B, 1944 const FieldRegion* R) { 1945 1946 // Check if the region has a binding. 1947 if (const std::optional<SVal> &V = B.getDirectBinding(R)) 1948 return *V; 1949 1950 // If the containing record was initialized, try to get its constant value. 1951 const FieldDecl *FD = R->getDecl(); 1952 QualType Ty = FD->getType(); 1953 const MemRegion* superR = R->getSuperRegion(); 1954 if (const auto *VR = dyn_cast<VarRegion>(superR)) { 1955 const VarDecl *VD = VR->getDecl(); 1956 QualType RecordVarTy = VD->getType(); 1957 unsigned Index = FD->getFieldIndex(); 1958 // Either the record variable or the field has an initializer that we can 1959 // trust. We trust initializers of constants and, additionally, respect 1960 // initializers of globals when analyzing main(). 1961 if (RecordVarTy.isConstQualified() || Ty.isConstQualified() || 1962 (B.isMainAnalysis() && VD->hasGlobalStorage())) 1963 if (const Expr *Init = VD->getAnyInitializer()) 1964 if (const auto *InitList = dyn_cast<InitListExpr>(Init)) { 1965 if (Index < InitList->getNumInits()) { 1966 if (const Expr *FieldInit = InitList->getInit(Index)) 1967 if (std::optional<SVal> V = svalBuilder.getConstantVal(FieldInit)) 1968 return *V; 1969 } else { 1970 return svalBuilder.makeZeroVal(Ty); 1971 } 1972 } 1973 } 1974 1975 // Handle the case where we are accessing into a larger scalar object. 1976 // For example, this handles: 1977 // struct header { 1978 // unsigned a : 1; 1979 // unsigned b : 1; 1980 // }; 1981 // struct parse_t { 1982 // unsigned bits0 : 1; 1983 // unsigned bits2 : 2; // <-- header 1984 // unsigned bits4 : 4; 1985 // }; 1986 // int parse(parse_t *p) { 1987 // unsigned copy = p->bits2; 1988 // header *bits = (header *)© 1989 // return bits->b; <-- here 1990 // } 1991 if (const auto *Base = dyn_cast<TypedValueRegion>(R->getBaseRegion())) 1992 if (auto V = getDerivedSymbolForBinding(B, Base, R, Ctx, svalBuilder)) 1993 return *V; 1994 1995 return getBindingForFieldOrElementCommon(B, R, Ty); 1996 } 1997 1998 std::optional<SVal> RegionStoreManager::getBindingForDerivedDefaultValue( 1999 RegionBindingsConstRef B, const MemRegion *superR, 2000 const TypedValueRegion *R, QualType Ty) { 2001 2002 if (const std::optional<SVal> &D = B.getDefaultBinding(superR)) { 2003 SVal val = *D; 2004 if (SymbolRef parentSym = val.getAsSymbol()) 2005 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); 2006 2007 if (val.isZeroConstant()) 2008 return svalBuilder.makeZeroVal(Ty); 2009 2010 if (val.isUnknownOrUndef()) 2011 return val; 2012 2013 // Lazy bindings are usually handled through getExistingLazyBinding(). 2014 // We should unify these two code paths at some point. 2015 if (isa<nonloc::LazyCompoundVal, nonloc::CompoundVal>(val)) 2016 return val; 2017 2018 llvm_unreachable("Unknown default value"); 2019 } 2020 2021 return std::nullopt; 2022 } 2023 2024 SVal RegionStoreManager::getLazyBinding(const SubRegion *LazyBindingRegion, 2025 RegionBindingsRef LazyBinding) { 2026 SVal Result; 2027 if (const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion)) 2028 Result = getBindingForElement(LazyBinding, ER); 2029 else 2030 Result = getBindingForField(LazyBinding, 2031 cast<FieldRegion>(LazyBindingRegion)); 2032 2033 // FIXME: This is a hack to deal with RegionStore's inability to distinguish a 2034 // default value for /part/ of an aggregate from a default value for the 2035 // /entire/ aggregate. The most common case of this is when struct Outer 2036 // has as its first member a struct Inner, which is copied in from a stack 2037 // variable. In this case, even if the Outer's default value is symbolic, 0, 2038 // or unknown, it gets overridden by the Inner's default value of undefined. 2039 // 2040 // This is a general problem -- if the Inner is zero-initialized, the Outer 2041 // will now look zero-initialized. The proper way to solve this is with a 2042 // new version of RegionStore that tracks the extent of a binding as well 2043 // as the offset. 2044 // 2045 // This hack only takes care of the undefined case because that can very 2046 // quickly result in a warning. 2047 if (Result.isUndef()) 2048 Result = UnknownVal(); 2049 2050 return Result; 2051 } 2052 2053 SVal 2054 RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B, 2055 const TypedValueRegion *R, 2056 QualType Ty) { 2057 2058 // At this point we have already checked in either getBindingForElement or 2059 // getBindingForField if 'R' has a direct binding. 2060 2061 // Lazy binding? 2062 Store lazyBindingStore = nullptr; 2063 const SubRegion *lazyBindingRegion = nullptr; 2064 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R); 2065 if (lazyBindingRegion) 2066 return getLazyBinding(lazyBindingRegion, 2067 getRegionBindings(lazyBindingStore)); 2068 2069 // Record whether or not we see a symbolic index. That can completely 2070 // be out of scope of our lookup. 2071 bool hasSymbolicIndex = false; 2072 2073 // FIXME: This is a hack to deal with RegionStore's inability to distinguish a 2074 // default value for /part/ of an aggregate from a default value for the 2075 // /entire/ aggregate. The most common case of this is when struct Outer 2076 // has as its first member a struct Inner, which is copied in from a stack 2077 // variable. In this case, even if the Outer's default value is symbolic, 0, 2078 // or unknown, it gets overridden by the Inner's default value of undefined. 2079 // 2080 // This is a general problem -- if the Inner is zero-initialized, the Outer 2081 // will now look zero-initialized. The proper way to solve this is with a 2082 // new version of RegionStore that tracks the extent of a binding as well 2083 // as the offset. 2084 // 2085 // This hack only takes care of the undefined case because that can very 2086 // quickly result in a warning. 2087 bool hasPartialLazyBinding = false; 2088 2089 const SubRegion *SR = R; 2090 while (SR) { 2091 const MemRegion *Base = SR->getSuperRegion(); 2092 if (std::optional<SVal> D = 2093 getBindingForDerivedDefaultValue(B, Base, R, Ty)) { 2094 if (D->getAs<nonloc::LazyCompoundVal>()) { 2095 hasPartialLazyBinding = true; 2096 break; 2097 } 2098 2099 return *D; 2100 } 2101 2102 if (const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) { 2103 NonLoc index = ER->getIndex(); 2104 if (!index.isConstant()) 2105 hasSymbolicIndex = true; 2106 } 2107 2108 // If our super region is a field or element itself, walk up the region 2109 // hierarchy to see if there is a default value installed in an ancestor. 2110 SR = dyn_cast<SubRegion>(Base); 2111 } 2112 2113 if (R->hasStackNonParametersStorage()) { 2114 if (isa<ElementRegion>(R)) { 2115 // Currently we don't reason specially about Clang-style vectors. Check 2116 // if superR is a vector and if so return Unknown. 2117 if (const TypedValueRegion *typedSuperR = 2118 dyn_cast<TypedValueRegion>(R->getSuperRegion())) { 2119 if (typedSuperR->getValueType()->isVectorType()) 2120 return UnknownVal(); 2121 } 2122 } 2123 2124 // FIXME: We also need to take ElementRegions with symbolic indexes into 2125 // account. This case handles both directly accessing an ElementRegion 2126 // with a symbolic offset, but also fields within an element with 2127 // a symbolic offset. 2128 if (hasSymbolicIndex) 2129 return UnknownVal(); 2130 2131 // Additionally allow introspection of a block's internal layout. 2132 // Try to get direct binding if all other attempts failed thus far. 2133 // Else, return UndefinedVal() 2134 if (!hasPartialLazyBinding && !isa<BlockDataRegion>(R->getBaseRegion())) { 2135 if (const std::optional<SVal> &V = B.getDefaultBinding(R)) 2136 return *V; 2137 return UndefinedVal(); 2138 } 2139 } 2140 2141 // All other values are symbolic. 2142 return svalBuilder.getRegionValueSymbolVal(R); 2143 } 2144 2145 SVal RegionStoreManager::getBindingForObjCIvar(RegionBindingsConstRef B, 2146 const ObjCIvarRegion* R) { 2147 // Check if the region has a binding. 2148 if (const std::optional<SVal> &V = B.getDirectBinding(R)) 2149 return *V; 2150 2151 const MemRegion *superR = R->getSuperRegion(); 2152 2153 // Check if the super region has a default binding. 2154 if (const std::optional<SVal> &V = B.getDefaultBinding(superR)) { 2155 if (SymbolRef parentSym = V->getAsSymbol()) 2156 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); 2157 2158 // Other cases: give up. 2159 return UnknownVal(); 2160 } 2161 2162 return getBindingForLazySymbol(R); 2163 } 2164 2165 SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B, 2166 const VarRegion *R) { 2167 2168 // Check if the region has a binding. 2169 if (std::optional<SVal> V = B.getDirectBinding(R)) 2170 return *V; 2171 2172 if (std::optional<SVal> V = B.getDefaultBinding(R)) 2173 return *V; 2174 2175 // Lazily derive a value for the VarRegion. 2176 const VarDecl *VD = R->getDecl(); 2177 const MemSpaceRegion *MS = R->getMemorySpace(); 2178 2179 // Arguments are always symbolic. 2180 if (isa<StackArgumentsSpaceRegion>(MS)) 2181 return svalBuilder.getRegionValueSymbolVal(R); 2182 2183 // Is 'VD' declared constant? If so, retrieve the constant value. 2184 if (VD->getType().isConstQualified()) { 2185 if (const Expr *Init = VD->getAnyInitializer()) { 2186 if (std::optional<SVal> V = svalBuilder.getConstantVal(Init)) 2187 return *V; 2188 2189 // If the variable is const qualified and has an initializer but 2190 // we couldn't evaluate initializer to a value, treat the value as 2191 // unknown. 2192 return UnknownVal(); 2193 } 2194 } 2195 2196 // This must come after the check for constants because closure-captured 2197 // constant variables may appear in UnknownSpaceRegion. 2198 if (isa<UnknownSpaceRegion>(MS)) 2199 return svalBuilder.getRegionValueSymbolVal(R); 2200 2201 if (isa<GlobalsSpaceRegion>(MS)) { 2202 QualType T = VD->getType(); 2203 2204 // If we're in main(), then global initializers have not become stale yet. 2205 if (B.isMainAnalysis()) 2206 if (const Expr *Init = VD->getAnyInitializer()) 2207 if (std::optional<SVal> V = svalBuilder.getConstantVal(Init)) 2208 return *V; 2209 2210 // Function-scoped static variables are default-initialized to 0; if they 2211 // have an initializer, it would have been processed by now. 2212 // FIXME: This is only true when we're starting analysis from main(). 2213 // We're losing a lot of coverage here. 2214 if (isa<StaticGlobalSpaceRegion>(MS)) 2215 return svalBuilder.makeZeroVal(T); 2216 2217 if (std::optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) { 2218 assert(!V->getAs<nonloc::LazyCompoundVal>()); 2219 return *V; 2220 } 2221 2222 return svalBuilder.getRegionValueSymbolVal(R); 2223 } 2224 2225 return UndefinedVal(); 2226 } 2227 2228 SVal RegionStoreManager::getBindingForLazySymbol(const TypedValueRegion *R) { 2229 // All other values are symbolic. 2230 return svalBuilder.getRegionValueSymbolVal(R); 2231 } 2232 2233 const RegionStoreManager::SValListTy & 2234 RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) { 2235 // First, check the cache. 2236 LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.getCVData()); 2237 if (I != LazyBindingsMap.end()) 2238 return I->second; 2239 2240 // If we don't have a list of values cached, start constructing it. 2241 SValListTy List; 2242 2243 const SubRegion *LazyR = LCV.getRegion(); 2244 RegionBindingsRef B = getRegionBindings(LCV.getStore()); 2245 2246 // If this region had /no/ bindings at the time, there are no interesting 2247 // values to return. 2248 const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion()); 2249 if (!Cluster) 2250 return (LazyBindingsMap[LCV.getCVData()] = std::move(List)); 2251 2252 SmallVector<BindingPair, 32> Bindings; 2253 collectSubRegionBindings(Bindings, svalBuilder, *Cluster, LazyR, 2254 /*IncludeAllDefaultBindings=*/true); 2255 for (SVal V : llvm::make_second_range(Bindings)) { 2256 if (V.isUnknownOrUndef() || V.isConstant()) 2257 continue; 2258 2259 if (auto InnerLCV = V.getAs<nonloc::LazyCompoundVal>()) { 2260 const SValListTy &InnerList = getInterestingValues(*InnerLCV); 2261 List.insert(List.end(), InnerList.begin(), InnerList.end()); 2262 } 2263 2264 List.push_back(V); 2265 } 2266 2267 return (LazyBindingsMap[LCV.getCVData()] = std::move(List)); 2268 } 2269 2270 NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B, 2271 const TypedValueRegion *R) { 2272 if (std::optional<nonloc::LazyCompoundVal> V = 2273 getExistingLazyBinding(svalBuilder, B, R, false)) 2274 return *V; 2275 2276 return svalBuilder.makeLazyCompoundVal(StoreRef(B.asStore(), *this), R); 2277 } 2278 2279 static bool isRecordEmpty(const RecordDecl *RD) { 2280 if (!RD->field_empty()) 2281 return false; 2282 if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) 2283 return CRD->getNumBases() == 0; 2284 return true; 2285 } 2286 2287 SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B, 2288 const TypedValueRegion *R) { 2289 const RecordDecl *RD = R->getValueType()->castAs<RecordType>()->getDecl(); 2290 if (!RD->getDefinition() || isRecordEmpty(RD)) 2291 return UnknownVal(); 2292 2293 return createLazyBinding(B, R); 2294 } 2295 2296 SVal RegionStoreManager::getBindingForArray(RegionBindingsConstRef B, 2297 const TypedValueRegion *R) { 2298 assert(Ctx.getAsConstantArrayType(R->getValueType()) && 2299 "Only constant array types can have compound bindings."); 2300 2301 return createLazyBinding(B, R); 2302 } 2303 2304 bool RegionStoreManager::includedInBindings(Store store, 2305 const MemRegion *region) const { 2306 RegionBindingsRef B = getRegionBindings(store); 2307 region = region->getBaseRegion(); 2308 2309 // Quick path: if the base is the head of a cluster, the region is live. 2310 if (B.lookup(region)) 2311 return true; 2312 2313 // Slow path: if the region is the VALUE of any binding, it is live. 2314 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) { 2315 const ClusterBindings &Cluster = RI.getData(); 2316 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end(); 2317 CI != CE; ++CI) { 2318 SVal D = CI.getData(); 2319 if (const MemRegion *R = D.getAsRegion()) 2320 if (R->getBaseRegion() == region) 2321 return true; 2322 } 2323 } 2324 2325 return false; 2326 } 2327 2328 //===----------------------------------------------------------------------===// 2329 // Binding values to regions. 2330 //===----------------------------------------------------------------------===// 2331 2332 StoreRef RegionStoreManager::killBinding(Store ST, Loc L) { 2333 if (std::optional<loc::MemRegionVal> LV = L.getAs<loc::MemRegionVal>()) 2334 if (const MemRegion* R = LV->getRegion()) 2335 return StoreRef(getRegionBindings(ST).removeBinding(R) 2336 .asImmutableMap() 2337 .getRootWithoutRetain(), 2338 *this); 2339 2340 return StoreRef(ST, *this); 2341 } 2342 2343 RegionBindingsRef 2344 RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) { 2345 // We only care about region locations. 2346 auto MemRegVal = L.getAs<loc::MemRegionVal>(); 2347 if (!MemRegVal) 2348 return B; 2349 2350 const MemRegion *R = MemRegVal->getRegion(); 2351 2352 // Check if the region is a struct region. 2353 if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) { 2354 QualType Ty = TR->getValueType(); 2355 if (Ty->isArrayType()) 2356 return bindArray(B, TR, V); 2357 if (Ty->isStructureOrClassType()) 2358 return bindStruct(B, TR, V); 2359 if (Ty->isVectorType()) 2360 return bindVector(B, TR, V); 2361 if (Ty->isUnionType()) 2362 return bindAggregate(B, TR, V); 2363 } 2364 2365 // Binding directly to a symbolic region should be treated as binding 2366 // to element 0. 2367 if (const auto *SymReg = dyn_cast<SymbolicRegion>(R)) { 2368 QualType Ty = SymReg->getPointeeStaticType(); 2369 if (Ty->isVoidType()) 2370 Ty = StateMgr.getContext().CharTy; 2371 R = GetElementZeroRegion(SymReg, Ty); 2372 } 2373 2374 assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) && 2375 "'this' pointer is not an l-value and is not assignable"); 2376 2377 // Clear out bindings that may overlap with this binding. 2378 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R)); 2379 2380 // LazyCompoundVals should be always bound as 'default' bindings. 2381 auto KeyKind = isa<nonloc::LazyCompoundVal>(V) ? BindingKey::Default 2382 : BindingKey::Direct; 2383 return NewB.addBinding(BindingKey::Make(R, KeyKind), V); 2384 } 2385 2386 RegionBindingsRef 2387 RegionStoreManager::setImplicitDefaultValue(RegionBindingsConstRef B, 2388 const MemRegion *R, 2389 QualType T) { 2390 SVal V; 2391 2392 if (Loc::isLocType(T)) 2393 V = svalBuilder.makeNullWithType(T); 2394 else if (T->isIntegralOrEnumerationType()) 2395 V = svalBuilder.makeZeroVal(T); 2396 else if (T->isStructureOrClassType() || T->isArrayType()) { 2397 // Set the default value to a zero constant when it is a structure 2398 // or array. The type doesn't really matter. 2399 V = svalBuilder.makeZeroVal(Ctx.IntTy); 2400 } 2401 else { 2402 // We can't represent values of this type, but we still need to set a value 2403 // to record that the region has been initialized. 2404 // If this assertion ever fires, a new case should be added above -- we 2405 // should know how to default-initialize any value we can symbolicate. 2406 assert(!SymbolManager::canSymbolicate(T) && "This type is representable"); 2407 V = UnknownVal(); 2408 } 2409 2410 return B.addBinding(R, BindingKey::Default, V); 2411 } 2412 2413 std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallArray( 2414 RegionBindingsConstRef B, const TypedValueRegion *R, const ArrayType *AT, 2415 nonloc::LazyCompoundVal LCV) { 2416 2417 auto CAT = dyn_cast<ConstantArrayType>(AT); 2418 2419 // If we don't know the size, create a lazyCompoundVal instead. 2420 if (!CAT) 2421 return std::nullopt; 2422 2423 QualType Ty = CAT->getElementType(); 2424 if (!(Ty->isScalarType() || Ty->isReferenceType())) 2425 return std::nullopt; 2426 2427 // If the array is too big, create a LCV instead. 2428 uint64_t ArrSize = CAT->getLimitedSize(); 2429 if (ArrSize > SmallArrayLimit) 2430 return std::nullopt; 2431 2432 RegionBindingsRef NewB = B; 2433 2434 for (uint64_t i = 0; i < ArrSize; ++i) { 2435 auto Idx = svalBuilder.makeArrayIndex(i); 2436 const ElementRegion *SrcER = 2437 MRMgr.getElementRegion(Ty, Idx, LCV.getRegion(), Ctx); 2438 SVal V = getBindingForElement(getRegionBindings(LCV.getStore()), SrcER); 2439 2440 const ElementRegion *DstER = MRMgr.getElementRegion(Ty, Idx, R, Ctx); 2441 NewB = bind(NewB, loc::MemRegionVal(DstER), V); 2442 } 2443 2444 return NewB; 2445 } 2446 2447 RegionBindingsRef 2448 RegionStoreManager::bindArray(RegionBindingsConstRef B, 2449 const TypedValueRegion* R, 2450 SVal Init) { 2451 2452 const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType())); 2453 QualType ElementTy = AT->getElementType(); 2454 std::optional<uint64_t> Size; 2455 2456 if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT)) 2457 Size = CAT->getZExtSize(); 2458 2459 // Check if the init expr is a literal. If so, bind the rvalue instead. 2460 // FIXME: It's not responsibility of the Store to transform this lvalue 2461 // to rvalue. ExprEngine or maybe even CFG should do this before binding. 2462 if (std::optional<loc::MemRegionVal> MRV = Init.getAs<loc::MemRegionVal>()) { 2463 SVal V = getBinding(B.asStore(), *MRV, R->getValueType()); 2464 return bindAggregate(B, R, V); 2465 } 2466 2467 // Handle lazy compound values. 2468 if (std::optional<nonloc::LazyCompoundVal> LCV = 2469 Init.getAs<nonloc::LazyCompoundVal>()) { 2470 if (std::optional<RegionBindingsRef> NewB = 2471 tryBindSmallArray(B, R, AT, *LCV)) 2472 return *NewB; 2473 2474 return bindAggregate(B, R, Init); 2475 } 2476 2477 if (Init.isUnknown()) 2478 return bindAggregate(B, R, UnknownVal()); 2479 2480 // Remaining case: explicit compound values. 2481 const nonloc::CompoundVal& CV = Init.castAs<nonloc::CompoundVal>(); 2482 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end(); 2483 uint64_t i = 0; 2484 2485 RegionBindingsRef NewB(B); 2486 2487 for (; Size ? i < *Size : true; ++i, ++VI) { 2488 // The init list might be shorter than the array length. 2489 if (VI == VE) 2490 break; 2491 2492 NonLoc Idx = svalBuilder.makeArrayIndex(i); 2493 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx); 2494 2495 if (ElementTy->isStructureOrClassType()) 2496 NewB = bindStruct(NewB, ER, *VI); 2497 else if (ElementTy->isArrayType()) 2498 NewB = bindArray(NewB, ER, *VI); 2499 else 2500 NewB = bind(NewB, loc::MemRegionVal(ER), *VI); 2501 } 2502 2503 // If the init list is shorter than the array length (or the array has 2504 // variable length), set the array default value. Values that are already set 2505 // are not overwritten. 2506 if (!Size || i < *Size) 2507 NewB = setImplicitDefaultValue(NewB, R, ElementTy); 2508 2509 return NewB; 2510 } 2511 2512 RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B, 2513 const TypedValueRegion* R, 2514 SVal V) { 2515 QualType T = R->getValueType(); 2516 const VectorType *VT = T->castAs<VectorType>(); // Use castAs for typedefs. 2517 2518 // Handle lazy compound values and symbolic values. 2519 if (isa<nonloc::LazyCompoundVal, nonloc::SymbolVal>(V)) 2520 return bindAggregate(B, R, V); 2521 2522 // We may get non-CompoundVal accidentally due to imprecise cast logic or 2523 // that we are binding symbolic struct value. Kill the field values, and if 2524 // the value is symbolic go and bind it as a "default" binding. 2525 if (!isa<nonloc::CompoundVal>(V)) { 2526 return bindAggregate(B, R, UnknownVal()); 2527 } 2528 2529 QualType ElemType = VT->getElementType(); 2530 nonloc::CompoundVal CV = V.castAs<nonloc::CompoundVal>(); 2531 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end(); 2532 unsigned index = 0, numElements = VT->getNumElements(); 2533 RegionBindingsRef NewB(B); 2534 2535 for ( ; index != numElements ; ++index) { 2536 if (VI == VE) 2537 break; 2538 2539 NonLoc Idx = svalBuilder.makeArrayIndex(index); 2540 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx); 2541 2542 if (ElemType->isArrayType()) 2543 NewB = bindArray(NewB, ER, *VI); 2544 else if (ElemType->isStructureOrClassType()) 2545 NewB = bindStruct(NewB, ER, *VI); 2546 else 2547 NewB = bind(NewB, loc::MemRegionVal(ER), *VI); 2548 } 2549 return NewB; 2550 } 2551 2552 std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallStruct( 2553 RegionBindingsConstRef B, const TypedValueRegion *R, const RecordDecl *RD, 2554 nonloc::LazyCompoundVal LCV) { 2555 FieldVector Fields; 2556 2557 if (const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD)) 2558 if (Class->getNumBases() != 0 || Class->getNumVBases() != 0) 2559 return std::nullopt; 2560 2561 for (const auto *FD : RD->fields()) { 2562 if (FD->isUnnamedBitField()) 2563 continue; 2564 2565 // If there are too many fields, or if any of the fields are aggregates, 2566 // just use the LCV as a default binding. 2567 if (Fields.size() == SmallStructLimit) 2568 return std::nullopt; 2569 2570 QualType Ty = FD->getType(); 2571 2572 // Zero length arrays are basically no-ops, so we also ignore them here. 2573 if (Ty->isConstantArrayType() && 2574 Ctx.getConstantArrayElementCount(Ctx.getAsConstantArrayType(Ty)) == 0) 2575 continue; 2576 2577 if (!(Ty->isScalarType() || Ty->isReferenceType())) 2578 return std::nullopt; 2579 2580 Fields.push_back(FD); 2581 } 2582 2583 RegionBindingsRef NewB = B; 2584 2585 for (const FieldDecl *Field : Fields) { 2586 const FieldRegion *SourceFR = MRMgr.getFieldRegion(Field, LCV.getRegion()); 2587 SVal V = getBindingForField(getRegionBindings(LCV.getStore()), SourceFR); 2588 2589 const FieldRegion *DestFR = MRMgr.getFieldRegion(Field, R); 2590 NewB = bind(NewB, loc::MemRegionVal(DestFR), V); 2591 } 2592 2593 return NewB; 2594 } 2595 2596 RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B, 2597 const TypedValueRegion *R, 2598 SVal V) { 2599 QualType T = R->getValueType(); 2600 assert(T->isStructureOrClassType()); 2601 2602 const RecordType* RT = T->castAs<RecordType>(); 2603 const RecordDecl *RD = RT->getDecl(); 2604 2605 if (!RD->isCompleteDefinition()) 2606 return B; 2607 2608 // Handle lazy compound values and symbolic values. 2609 if (std::optional<nonloc::LazyCompoundVal> LCV = 2610 V.getAs<nonloc::LazyCompoundVal>()) { 2611 if (std::optional<RegionBindingsRef> NewB = 2612 tryBindSmallStruct(B, R, RD, *LCV)) 2613 return *NewB; 2614 return bindAggregate(B, R, V); 2615 } 2616 if (isa<nonloc::SymbolVal>(V)) 2617 return bindAggregate(B, R, V); 2618 2619 // We may get non-CompoundVal accidentally due to imprecise cast logic or 2620 // that we are binding symbolic struct value. Kill the field values, and if 2621 // the value is symbolic go and bind it as a "default" binding. 2622 if (V.isUnknown() || !isa<nonloc::CompoundVal>(V)) 2623 return bindAggregate(B, R, UnknownVal()); 2624 2625 // The raw CompoundVal is essentially a symbolic InitListExpr: an (immutable) 2626 // list of other values. It appears pretty much only when there's an actual 2627 // initializer list expression in the program, and the analyzer tries to 2628 // unwrap it as soon as possible. 2629 // This code is where such unwrap happens: when the compound value is put into 2630 // the object that it was supposed to initialize (it's an *initializer* list, 2631 // after all), instead of binding the whole value to the whole object, we bind 2632 // sub-values to sub-objects. Sub-values may themselves be compound values, 2633 // and in this case the procedure becomes recursive. 2634 // FIXME: The annoying part about compound values is that they don't carry 2635 // any sort of information about which value corresponds to which sub-object. 2636 // It's simply a list of values in the middle of nowhere; we expect to match 2637 // them to sub-objects, essentially, "by index": first value binds to 2638 // the first field, second value binds to the second field, etc. 2639 // It would have been much safer to organize non-lazy compound values as 2640 // a mapping from fields/bases to values. 2641 const nonloc::CompoundVal& CV = V.castAs<nonloc::CompoundVal>(); 2642 nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end(); 2643 2644 RegionBindingsRef NewB(B); 2645 2646 // In C++17 aggregates may have base classes, handle those as well. 2647 // They appear before fields in the initializer list / compound value. 2648 if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) { 2649 // If the object was constructed with a constructor, its value is a 2650 // LazyCompoundVal. If it's a raw CompoundVal, it means that we're 2651 // performing aggregate initialization. The only exception from this 2652 // rule is sending an Objective-C++ message that returns a C++ object 2653 // to a nil receiver; in this case the semantics is to return a 2654 // zero-initialized object even if it's a C++ object that doesn't have 2655 // this sort of constructor; the CompoundVal is empty in this case. 2656 assert((CRD->isAggregate() || (Ctx.getLangOpts().ObjC && VI == VE)) && 2657 "Non-aggregates are constructed with a constructor!"); 2658 2659 for (const auto &B : CRD->bases()) { 2660 // (Multiple inheritance is fine though.) 2661 assert(!B.isVirtual() && "Aggregates cannot have virtual base classes!"); 2662 2663 if (VI == VE) 2664 break; 2665 2666 QualType BTy = B.getType(); 2667 assert(BTy->isStructureOrClassType() && "Base classes must be classes!"); 2668 2669 const CXXRecordDecl *BRD = BTy->getAsCXXRecordDecl(); 2670 assert(BRD && "Base classes must be C++ classes!"); 2671 2672 const CXXBaseObjectRegion *BR = 2673 MRMgr.getCXXBaseObjectRegion(BRD, R, /*IsVirtual=*/false); 2674 2675 NewB = bindStruct(NewB, BR, *VI); 2676 2677 ++VI; 2678 } 2679 } 2680 2681 RecordDecl::field_iterator FI, FE; 2682 2683 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) { 2684 2685 if (VI == VE) 2686 break; 2687 2688 // Skip any unnamed bitfields to stay in sync with the initializers. 2689 if (FI->isUnnamedBitField()) 2690 continue; 2691 2692 QualType FTy = FI->getType(); 2693 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R); 2694 2695 if (FTy->isArrayType()) 2696 NewB = bindArray(NewB, FR, *VI); 2697 else if (FTy->isStructureOrClassType()) 2698 NewB = bindStruct(NewB, FR, *VI); 2699 else 2700 NewB = bind(NewB, loc::MemRegionVal(FR), *VI); 2701 ++VI; 2702 } 2703 2704 // There may be fewer values in the initialize list than the fields of struct. 2705 if (FI != FE) { 2706 NewB = NewB.addBinding(R, BindingKey::Default, 2707 svalBuilder.makeIntVal(0, false)); 2708 } 2709 2710 return NewB; 2711 } 2712 2713 RegionBindingsRef 2714 RegionStoreManager::bindAggregate(RegionBindingsConstRef B, 2715 const TypedRegion *R, 2716 SVal Val) { 2717 // Remove the old bindings, using 'R' as the root of all regions 2718 // we will invalidate. Then add the new binding. 2719 return removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val); 2720 } 2721 2722 //===----------------------------------------------------------------------===// 2723 // State pruning. 2724 //===----------------------------------------------------------------------===// 2725 2726 namespace { 2727 class RemoveDeadBindingsWorker 2728 : public ClusterAnalysis<RemoveDeadBindingsWorker> { 2729 SmallVector<const SymbolicRegion *, 12> Postponed; 2730 SymbolReaper &SymReaper; 2731 const StackFrameContext *CurrentLCtx; 2732 2733 public: 2734 RemoveDeadBindingsWorker(RegionStoreManager &rm, 2735 ProgramStateManager &stateMgr, 2736 RegionBindingsRef b, SymbolReaper &symReaper, 2737 const StackFrameContext *LCtx) 2738 : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr, b), 2739 SymReaper(symReaper), CurrentLCtx(LCtx) {} 2740 2741 // Called by ClusterAnalysis. 2742 void VisitAddedToCluster(const MemRegion *baseR, const ClusterBindings &C); 2743 void VisitCluster(const MemRegion *baseR, const ClusterBindings *C); 2744 using ClusterAnalysis<RemoveDeadBindingsWorker>::VisitCluster; 2745 2746 using ClusterAnalysis::AddToWorkList; 2747 2748 bool AddToWorkList(const MemRegion *R); 2749 2750 bool UpdatePostponed(); 2751 void VisitBinding(SVal V); 2752 }; 2753 } 2754 2755 bool RemoveDeadBindingsWorker::AddToWorkList(const MemRegion *R) { 2756 const MemRegion *BaseR = R->getBaseRegion(); 2757 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR)); 2758 } 2759 2760 void RemoveDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR, 2761 const ClusterBindings &C) { 2762 2763 if (const VarRegion *VR = dyn_cast<VarRegion>(baseR)) { 2764 if (SymReaper.isLive(VR)) 2765 AddToWorkList(baseR, &C); 2766 2767 return; 2768 } 2769 2770 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) { 2771 if (SymReaper.isLive(SR->getSymbol())) 2772 AddToWorkList(SR, &C); 2773 else 2774 Postponed.push_back(SR); 2775 2776 return; 2777 } 2778 2779 if (isa<NonStaticGlobalSpaceRegion>(baseR)) { 2780 AddToWorkList(baseR, &C); 2781 return; 2782 } 2783 2784 // CXXThisRegion in the current or parent location context is live. 2785 if (const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) { 2786 const auto *StackReg = 2787 cast<StackArgumentsSpaceRegion>(TR->getSuperRegion()); 2788 const StackFrameContext *RegCtx = StackReg->getStackFrame(); 2789 if (CurrentLCtx && 2790 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx))) 2791 AddToWorkList(TR, &C); 2792 } 2793 } 2794 2795 void RemoveDeadBindingsWorker::VisitCluster(const MemRegion *baseR, 2796 const ClusterBindings *C) { 2797 if (!C) 2798 return; 2799 2800 // Mark the symbol for any SymbolicRegion with live bindings as live itself. 2801 // This means we should continue to track that symbol. 2802 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR)) 2803 SymReaper.markLive(SymR->getSymbol()); 2804 2805 for (const auto &[Key, Val] : *C) { 2806 // Element index of a binding key is live. 2807 SymReaper.markElementIndicesLive(Key.getRegion()); 2808 2809 VisitBinding(Val); 2810 } 2811 } 2812 2813 void RemoveDeadBindingsWorker::VisitBinding(SVal V) { 2814 // Is it a LazyCompoundVal? All referenced regions are live as well. 2815 // The LazyCompoundVal itself is not live but should be readable. 2816 if (auto LCS = V.getAs<nonloc::LazyCompoundVal>()) { 2817 SymReaper.markLazilyCopied(LCS->getRegion()); 2818 2819 for (SVal V : RM.getInterestingValues(*LCS)) { 2820 if (auto DepLCS = V.getAs<nonloc::LazyCompoundVal>()) 2821 SymReaper.markLazilyCopied(DepLCS->getRegion()); 2822 else 2823 VisitBinding(V); 2824 } 2825 2826 return; 2827 } 2828 2829 // If V is a region, then add it to the worklist. 2830 if (const MemRegion *R = V.getAsRegion()) { 2831 AddToWorkList(R); 2832 SymReaper.markLive(R); 2833 2834 // All regions captured by a block are also live. 2835 if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) { 2836 for (auto Var : BR->referenced_vars()) 2837 AddToWorkList(Var.getCapturedRegion()); 2838 } 2839 } 2840 2841 2842 // Update the set of live symbols. 2843 for (SymbolRef Sym : V.symbols()) 2844 SymReaper.markLive(Sym); 2845 } 2846 2847 bool RemoveDeadBindingsWorker::UpdatePostponed() { 2848 // See if any postponed SymbolicRegions are actually live now, after 2849 // having done a scan. 2850 bool Changed = false; 2851 2852 for (const SymbolicRegion *SR : Postponed) { 2853 if (SymReaper.isLive(SR->getSymbol())) { 2854 Changed |= AddToWorkList(SR); 2855 SR = nullptr; 2856 } 2857 } 2858 2859 return Changed; 2860 } 2861 2862 StoreRef RegionStoreManager::removeDeadBindings(Store store, 2863 const StackFrameContext *LCtx, 2864 SymbolReaper& SymReaper) { 2865 RegionBindingsRef B = getRegionBindings(store); 2866 RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, LCtx); 2867 W.GenerateClusters(); 2868 2869 // Enqueue the region roots onto the worklist. 2870 for (const MemRegion *Reg : SymReaper.regions()) { 2871 W.AddToWorkList(Reg); 2872 } 2873 2874 do W.RunWorkList(); while (W.UpdatePostponed()); 2875 2876 // We have now scanned the store, marking reachable regions and symbols 2877 // as live. We now remove all the regions that are dead from the store 2878 // as well as update DSymbols with the set symbols that are now dead. 2879 for (const MemRegion *Base : llvm::make_first_range(B)) { 2880 // If the cluster has been visited, we know the region has been marked. 2881 // Otherwise, remove the dead entry. 2882 if (!W.isVisited(Base)) 2883 B = B.remove(Base); 2884 } 2885 2886 return StoreRef(B.asStore(), *this); 2887 } 2888 2889 //===----------------------------------------------------------------------===// 2890 // Utility methods. 2891 //===----------------------------------------------------------------------===// 2892 2893 void RegionStoreManager::printJson(raw_ostream &Out, Store S, const char *NL, 2894 unsigned int Space, bool IsDot) const { 2895 RegionBindingsRef Bindings = getRegionBindings(S); 2896 2897 Indent(Out, Space, IsDot) << "\"store\": "; 2898 2899 if (Bindings.isEmpty()) { 2900 Out << "null," << NL; 2901 return; 2902 } 2903 2904 Out << "{ \"pointer\": \"" << Bindings.asStore() << "\", \"items\": [" << NL; 2905 Bindings.printJson(Out, NL, Space + 1, IsDot); 2906 Indent(Out, Space, IsDot) << "]}," << NL; 2907 } 2908