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