1 //==- MemRegion.h - Abstract memory regions for static analysis -*- 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 MemRegion and its subclasses. MemRegion defines a 10 // partially-typed abstraction of memory useful for path-sensitive dataflow 11 // analyses. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H 16 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H 17 18 #include "clang/AST/ASTContext.h" 19 #include "clang/AST/CharUnits.h" 20 #include "clang/AST/Decl.h" 21 #include "clang/AST/DeclObjC.h" 22 #include "clang/AST/DeclarationName.h" 23 #include "clang/AST/Expr.h" 24 #include "clang/AST/ExprObjC.h" 25 #include "clang/AST/Type.h" 26 #include "clang/Analysis/AnalysisDeclContext.h" 27 #include "clang/Basic/LLVM.h" 28 #include "clang/Basic/SourceLocation.h" 29 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 30 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" 31 #include "llvm/ADT/DenseMap.h" 32 #include "llvm/ADT/FoldingSet.h" 33 #include "llvm/ADT/Optional.h" 34 #include "llvm/ADT/PointerIntPair.h" 35 #include "llvm/Support/Allocator.h" 36 #include "llvm/Support/Casting.h" 37 #include <cassert> 38 #include <cstdint> 39 #include <limits> 40 #include <string> 41 #include <utility> 42 43 namespace clang { 44 45 class AnalysisDeclContext; 46 class CXXRecordDecl; 47 class Decl; 48 class LocationContext; 49 class StackFrameContext; 50 51 namespace ento { 52 53 class CodeTextRegion; 54 class MemRegion; 55 class MemRegionManager; 56 class MemSpaceRegion; 57 class SValBuilder; 58 class SymbolicRegion; 59 class VarRegion; 60 61 /// Represent a region's offset within the top level base region. 62 class RegionOffset { 63 /// The base region. 64 const MemRegion *R = nullptr; 65 66 /// The bit offset within the base region. Can be negative. 67 int64_t Offset; 68 69 public: 70 // We're using a const instead of an enumeration due to the size required; 71 // Visual Studio will only create enumerations of size int, not long long. 72 static const int64_t Symbolic = std::numeric_limits<int64_t>::max(); 73 74 RegionOffset() = default; 75 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} 76 77 /// It might return null. 78 const MemRegion *getRegion() const { return R; } 79 80 bool hasSymbolicOffset() const { return Offset == Symbolic; } 81 82 int64_t getOffset() const { 83 assert(!hasSymbolicOffset()); 84 return Offset; 85 } 86 87 bool isValid() const { return R; } 88 }; 89 90 //===----------------------------------------------------------------------===// 91 // Base region classes. 92 //===----------------------------------------------------------------------===// 93 94 /// MemRegion - The root abstract class for all memory regions. 95 class MemRegion : public llvm::FoldingSetNode { 96 public: 97 enum Kind { 98 #define REGION(Id, Parent) Id ## Kind, 99 #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last, 100 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" 101 }; 102 103 private: 104 const Kind kind; 105 mutable Optional<RegionOffset> cachedOffset; 106 107 protected: 108 MemRegion(Kind k) : kind(k) {} 109 virtual ~MemRegion(); 110 111 public: 112 ASTContext &getContext() const; 113 114 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 115 116 virtual MemRegionManager &getMemRegionManager() const = 0; 117 118 LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const; 119 120 LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const; 121 122 /// Recursively retrieve the region of the most derived class instance of 123 /// regions of C++ base class instances. 124 LLVM_ATTRIBUTE_RETURNS_NONNULL 125 const MemRegion *getMostDerivedObjectRegion() const; 126 127 /// Check if the region is a subregion of the given region. 128 /// Each region is a subregion of itself. 129 virtual bool isSubRegionOf(const MemRegion *R) const; 130 131 LLVM_ATTRIBUTE_RETURNS_NONNULL 132 const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const; 133 134 /// If this is a symbolic region, returns the region. Otherwise, 135 /// goes up the base chain looking for the first symbolic base region. 136 /// It might return null. 137 const SymbolicRegion *getSymbolicBase() const; 138 139 bool hasGlobalsOrParametersStorage() const; 140 141 bool hasStackStorage() const; 142 143 bool hasStackNonParametersStorage() const; 144 145 bool hasStackParametersStorage() const; 146 147 /// Compute the offset within the top level memory object. 148 RegionOffset getAsOffset() const; 149 150 /// Get a string representation of a region for debug use. 151 std::string getString() const; 152 153 virtual void dumpToStream(raw_ostream &os) const; 154 155 void dump() const; 156 157 /// Returns true if this region can be printed in a user-friendly way. 158 virtual bool canPrintPretty() const; 159 160 /// Print the region for use in diagnostics. 161 virtual void printPretty(raw_ostream &os) const; 162 163 /// Returns true if this region's textual representation can be used 164 /// as part of a larger expression. 165 virtual bool canPrintPrettyAsExpr() const; 166 167 /// Print the region as expression. 168 /// 169 /// When this region represents a subexpression, the method is for printing 170 /// an expression containing it. 171 virtual void printPrettyAsExpr(raw_ostream &os) const; 172 173 Kind getKind() const { return kind; } 174 175 template<typename RegionTy> const RegionTy* getAs() const; 176 template <typename RegionTy> 177 LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const; 178 179 virtual bool isBoundable() const { return false; } 180 181 /// Get descriptive name for memory region. The name is obtained from 182 /// the variable/field declaration retrieved from the memory region. 183 /// Regions that point to an element of an array are returned as: "arr[0]". 184 /// Regions that point to a struct are returned as: "st.var". 185 // 186 /// \param UseQuotes Set if the name should be quoted. 187 /// 188 /// \returns variable name for memory region 189 std::string getDescriptiveName(bool UseQuotes = true) const; 190 191 /// Retrieve source range from memory region. The range retrieval 192 /// is based on the decl obtained from the memory region. 193 /// For a VarRegion the range of the base region is returned. 194 /// For a FieldRegion the range of the field is returned. 195 /// If no declaration is found, an empty source range is returned. 196 /// The client is responsible for checking if the returned range is valid. 197 /// 198 /// \returns source range for declaration retrieved from memory region 199 SourceRange sourceRange() const; 200 }; 201 202 /// MemSpaceRegion - A memory region that represents a "memory space"; 203 /// for example, the set of global variables, the stack frame, etc. 204 class MemSpaceRegion : public MemRegion { 205 protected: 206 MemRegionManager &Mgr; 207 208 MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) { 209 assert(classof(this)); 210 } 211 212 MemRegionManager &getMemRegionManager() const override { return Mgr; } 213 214 public: 215 bool isBoundable() const override { return false; } 216 217 void Profile(llvm::FoldingSetNodeID &ID) const override; 218 219 static bool classof(const MemRegion *R) { 220 Kind k = R->getKind(); 221 return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES; 222 } 223 }; 224 225 /// CodeSpaceRegion - The memory space that holds the executable code of 226 /// functions and blocks. 227 class CodeSpaceRegion : public MemSpaceRegion { 228 friend class MemRegionManager; 229 230 CodeSpaceRegion(MemRegionManager &mgr) 231 : MemSpaceRegion(mgr, CodeSpaceRegionKind) {} 232 233 public: 234 void dumpToStream(raw_ostream &os) const override; 235 236 static bool classof(const MemRegion *R) { 237 return R->getKind() == CodeSpaceRegionKind; 238 } 239 }; 240 241 class GlobalsSpaceRegion : public MemSpaceRegion { 242 virtual void anchor(); 243 244 protected: 245 GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) { 246 assert(classof(this)); 247 } 248 249 public: 250 static bool classof(const MemRegion *R) { 251 Kind k = R->getKind(); 252 return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; 253 } 254 }; 255 256 /// The region of the static variables within the current CodeTextRegion 257 /// scope. 258 /// 259 /// Currently, only the static locals are placed there, so we know that these 260 /// variables do not get invalidated by calls to other functions. 261 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { 262 friend class MemRegionManager; 263 264 const CodeTextRegion *CR; 265 266 StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr) 267 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) { 268 assert(cr); 269 } 270 271 public: 272 void Profile(llvm::FoldingSetNodeID &ID) const override; 273 274 void dumpToStream(raw_ostream &os) const override; 275 276 LLVM_ATTRIBUTE_RETURNS_NONNULL 277 const CodeTextRegion *getCodeRegion() const { return CR; } 278 279 static bool classof(const MemRegion *R) { 280 return R->getKind() == StaticGlobalSpaceRegionKind; 281 } 282 }; 283 284 /// The region for all the non-static global variables. 285 /// 286 /// This class is further split into subclasses for efficient implementation of 287 /// invalidating a set of related global values as is done in 288 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent 289 /// globals, we invalidate the whole parent region). 290 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { 291 void anchor() override; 292 293 protected: 294 NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k) 295 : GlobalsSpaceRegion(mgr, k) { 296 assert(classof(this)); 297 } 298 299 public: 300 static bool classof(const MemRegion *R) { 301 Kind k = R->getKind(); 302 return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES && 303 k <= END_NON_STATIC_GLOBAL_MEMSPACES; 304 } 305 }; 306 307 /// The region containing globals which are defined in system/external 308 /// headers and are considered modifiable by system calls (ex: errno). 309 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { 310 friend class MemRegionManager; 311 312 GlobalSystemSpaceRegion(MemRegionManager &mgr) 313 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} 314 315 public: 316 void dumpToStream(raw_ostream &os) const override; 317 318 static bool classof(const MemRegion *R) { 319 return R->getKind() == GlobalSystemSpaceRegionKind; 320 } 321 }; 322 323 /// The region containing globals which are considered not to be modified 324 /// or point to data which could be modified as a result of a function call 325 /// (system or internal). Ex: Const global scalars would be modeled as part of 326 /// this region. This region also includes most system globals since they have 327 /// low chance of being modified. 328 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { 329 friend class MemRegionManager; 330 331 GlobalImmutableSpaceRegion(MemRegionManager &mgr) 332 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} 333 334 public: 335 void dumpToStream(raw_ostream &os) const override; 336 337 static bool classof(const MemRegion *R) { 338 return R->getKind() == GlobalImmutableSpaceRegionKind; 339 } 340 }; 341 342 /// The region containing globals which can be modified by calls to 343 /// "internally" defined functions - (for now just) functions other then system 344 /// calls. 345 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { 346 friend class MemRegionManager; 347 348 GlobalInternalSpaceRegion(MemRegionManager &mgr) 349 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} 350 351 public: 352 void dumpToStream(raw_ostream &os) const override; 353 354 static bool classof(const MemRegion *R) { 355 return R->getKind() == GlobalInternalSpaceRegionKind; 356 } 357 }; 358 359 class HeapSpaceRegion : public MemSpaceRegion { 360 friend class MemRegionManager; 361 362 HeapSpaceRegion(MemRegionManager &mgr) 363 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} 364 365 public: 366 void dumpToStream(raw_ostream &os) const override; 367 368 static bool classof(const MemRegion *R) { 369 return R->getKind() == HeapSpaceRegionKind; 370 } 371 }; 372 373 class UnknownSpaceRegion : public MemSpaceRegion { 374 friend class MemRegionManager; 375 376 UnknownSpaceRegion(MemRegionManager &mgr) 377 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} 378 379 public: 380 void dumpToStream(raw_ostream &os) const override; 381 382 static bool classof(const MemRegion *R) { 383 return R->getKind() == UnknownSpaceRegionKind; 384 } 385 }; 386 387 class StackSpaceRegion : public MemSpaceRegion { 388 virtual void anchor(); 389 390 const StackFrameContext *SFC; 391 392 protected: 393 StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc) 394 : MemSpaceRegion(mgr, k), SFC(sfc) { 395 assert(classof(this)); 396 assert(sfc); 397 } 398 399 public: 400 LLVM_ATTRIBUTE_RETURNS_NONNULL 401 const StackFrameContext *getStackFrame() const { return SFC; } 402 403 void Profile(llvm::FoldingSetNodeID &ID) const override; 404 405 static bool classof(const MemRegion *R) { 406 Kind k = R->getKind(); 407 return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES; 408 } 409 }; 410 411 class StackLocalsSpaceRegion : public StackSpaceRegion { 412 friend class MemRegionManager; 413 414 StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc) 415 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} 416 417 public: 418 void dumpToStream(raw_ostream &os) const override; 419 420 static bool classof(const MemRegion *R) { 421 return R->getKind() == StackLocalsSpaceRegionKind; 422 } 423 }; 424 425 class StackArgumentsSpaceRegion : public StackSpaceRegion { 426 private: 427 friend class MemRegionManager; 428 429 StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc) 430 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} 431 432 public: 433 void dumpToStream(raw_ostream &os) const override; 434 435 static bool classof(const MemRegion *R) { 436 return R->getKind() == StackArgumentsSpaceRegionKind; 437 } 438 }; 439 440 /// SubRegion - A region that subsets another larger region. Most regions 441 /// are subclasses of SubRegion. 442 class SubRegion : public MemRegion { 443 virtual void anchor(); 444 445 protected: 446 const MemRegion* superRegion; 447 448 SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) { 449 assert(classof(this)); 450 assert(sReg); 451 } 452 453 public: 454 LLVM_ATTRIBUTE_RETURNS_NONNULL 455 const MemRegion* getSuperRegion() const { 456 return superRegion; 457 } 458 459 MemRegionManager &getMemRegionManager() const override; 460 461 bool isSubRegionOf(const MemRegion* R) const override; 462 463 static bool classof(const MemRegion* R) { 464 return R->getKind() > END_MEMSPACES; 465 } 466 }; 467 468 //===----------------------------------------------------------------------===// 469 // MemRegion subclasses. 470 //===----------------------------------------------------------------------===// 471 472 /// AllocaRegion - A region that represents an untyped blob of bytes created 473 /// by a call to 'alloca'. 474 class AllocaRegion : public SubRegion { 475 friend class MemRegionManager; 476 477 // Block counter. Used to distinguish different pieces of memory allocated by 478 // alloca at the same call site. 479 unsigned Cnt; 480 481 const Expr *Ex; 482 483 AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion) 484 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) { 485 assert(Ex); 486 } 487 488 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, 489 unsigned Cnt, const MemRegion *superRegion); 490 491 public: 492 LLVM_ATTRIBUTE_RETURNS_NONNULL 493 const Expr *getExpr() const { return Ex; } 494 495 bool isBoundable() const override { return true; } 496 497 void Profile(llvm::FoldingSetNodeID& ID) const override; 498 499 void dumpToStream(raw_ostream &os) const override; 500 501 static bool classof(const MemRegion* R) { 502 return R->getKind() == AllocaRegionKind; 503 } 504 }; 505 506 /// TypedRegion - An abstract class representing regions that are typed. 507 class TypedRegion : public SubRegion { 508 void anchor() override; 509 510 protected: 511 TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) { 512 assert(classof(this)); 513 } 514 515 public: 516 virtual QualType getLocationType() const = 0; 517 518 QualType getDesugaredLocationType(ASTContext &Context) const { 519 return getLocationType().getDesugaredType(Context); 520 } 521 522 bool isBoundable() const override { return true; } 523 524 static bool classof(const MemRegion* R) { 525 unsigned k = R->getKind(); 526 return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS; 527 } 528 }; 529 530 /// TypedValueRegion - An abstract class representing regions having a typed value. 531 class TypedValueRegion : public TypedRegion { 532 void anchor() override; 533 534 protected: 535 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) { 536 assert(classof(this)); 537 } 538 539 public: 540 virtual QualType getValueType() const = 0; 541 542 QualType getLocationType() const override { 543 // FIXME: We can possibly optimize this later to cache this value. 544 QualType T = getValueType(); 545 ASTContext &ctx = getContext(); 546 if (T->getAs<ObjCObjectType>()) 547 return ctx.getObjCObjectPointerType(T); 548 return ctx.getPointerType(getValueType()); 549 } 550 551 QualType getDesugaredValueType(ASTContext &Context) const { 552 QualType T = getValueType(); 553 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; 554 } 555 556 static bool classof(const MemRegion* R) { 557 unsigned k = R->getKind(); 558 return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; 559 } 560 }; 561 562 class CodeTextRegion : public TypedRegion { 563 void anchor() override; 564 565 protected: 566 CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) { 567 assert(classof(this)); 568 } 569 570 public: 571 bool isBoundable() const override { return false; } 572 573 static bool classof(const MemRegion* R) { 574 Kind k = R->getKind(); 575 return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS; 576 } 577 }; 578 579 /// FunctionCodeRegion - A region that represents code texts of function. 580 class FunctionCodeRegion : public CodeTextRegion { 581 friend class MemRegionManager; 582 583 const NamedDecl *FD; 584 585 FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg) 586 : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) { 587 assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)); 588 } 589 590 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, 591 const MemRegion*); 592 593 public: 594 QualType getLocationType() const override { 595 const ASTContext &Ctx = getContext(); 596 if (const auto *D = dyn_cast<FunctionDecl>(FD)) { 597 return Ctx.getPointerType(D->getType()); 598 } 599 600 assert(isa<ObjCMethodDecl>(FD)); 601 assert(false && "Getting the type of ObjCMethod is not supported yet"); 602 603 // TODO: We might want to return a different type here (ex: id (*ty)(...)) 604 // depending on how it is used. 605 return {}; 606 } 607 608 const NamedDecl *getDecl() const { 609 return FD; 610 } 611 612 void dumpToStream(raw_ostream &os) const override; 613 614 void Profile(llvm::FoldingSetNodeID& ID) const override; 615 616 static bool classof(const MemRegion* R) { 617 return R->getKind() == FunctionCodeRegionKind; 618 } 619 }; 620 621 /// BlockCodeRegion - A region that represents code texts of blocks (closures). 622 /// Blocks are represented with two kinds of regions. BlockCodeRegions 623 /// represent the "code", while BlockDataRegions represent instances of blocks, 624 /// which correspond to "code+data". The distinction is important, because 625 /// like a closure a block captures the values of externally referenced 626 /// variables. 627 class BlockCodeRegion : public CodeTextRegion { 628 friend class MemRegionManager; 629 630 const BlockDecl *BD; 631 AnalysisDeclContext *AC; 632 CanQualType locTy; 633 634 BlockCodeRegion(const BlockDecl *bd, CanQualType lTy, 635 AnalysisDeclContext *ac, const CodeSpaceRegion* sreg) 636 : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) { 637 assert(bd); 638 assert(ac); 639 assert(lTy->getTypePtr()->isBlockPointerType()); 640 } 641 642 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, 643 CanQualType, const AnalysisDeclContext*, 644 const MemRegion*); 645 646 public: 647 QualType getLocationType() const override { 648 return locTy; 649 } 650 651 LLVM_ATTRIBUTE_RETURNS_NONNULL 652 const BlockDecl *getDecl() const { 653 return BD; 654 } 655 656 LLVM_ATTRIBUTE_RETURNS_NONNULL 657 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } 658 659 void dumpToStream(raw_ostream &os) const override; 660 661 void Profile(llvm::FoldingSetNodeID& ID) const override; 662 663 static bool classof(const MemRegion* R) { 664 return R->getKind() == BlockCodeRegionKind; 665 } 666 }; 667 668 /// BlockDataRegion - A region that represents a block instance. 669 /// Blocks are represented with two kinds of regions. BlockCodeRegions 670 /// represent the "code", while BlockDataRegions represent instances of blocks, 671 /// which correspond to "code+data". The distinction is important, because 672 /// like a closure a block captures the values of externally referenced 673 /// variables. 674 class BlockDataRegion : public TypedRegion { 675 friend class MemRegionManager; 676 677 const BlockCodeRegion *BC; 678 const LocationContext *LC; // Can be null 679 unsigned BlockCount; 680 void *ReferencedVars = nullptr; 681 void *OriginalVars = nullptr; 682 683 BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, 684 unsigned count, const MemSpaceRegion *sreg) 685 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), 686 BlockCount(count) { 687 assert(bc); 688 assert(bc->getDecl()); 689 assert(lc); 690 assert(isa<GlobalImmutableSpaceRegion>(sreg) || 691 isa<StackLocalsSpaceRegion>(sreg) || 692 isa<UnknownSpaceRegion>(sreg)); 693 } 694 695 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *, 696 const LocationContext *, unsigned, 697 const MemRegion *); 698 699 public: 700 LLVM_ATTRIBUTE_RETURNS_NONNULL 701 const BlockCodeRegion *getCodeRegion() const { return BC; } 702 703 LLVM_ATTRIBUTE_RETURNS_NONNULL 704 const BlockDecl *getDecl() const { return BC->getDecl(); } 705 706 QualType getLocationType() const override { return BC->getLocationType(); } 707 708 class referenced_vars_iterator { 709 const MemRegion * const *R; 710 const MemRegion * const *OriginalR; 711 712 public: 713 explicit referenced_vars_iterator(const MemRegion * const *r, 714 const MemRegion * const *originalR) 715 : R(r), OriginalR(originalR) {} 716 717 LLVM_ATTRIBUTE_RETURNS_NONNULL 718 const VarRegion *getCapturedRegion() const { 719 return cast<VarRegion>(*R); 720 } 721 722 LLVM_ATTRIBUTE_RETURNS_NONNULL 723 const VarRegion *getOriginalRegion() const { 724 return cast<VarRegion>(*OriginalR); 725 } 726 727 bool operator==(const referenced_vars_iterator &I) const { 728 assert((R == nullptr) == (I.R == nullptr)); 729 return I.R == R; 730 } 731 732 bool operator!=(const referenced_vars_iterator &I) const { 733 assert((R == nullptr) == (I.R == nullptr)); 734 return I.R != R; 735 } 736 737 referenced_vars_iterator &operator++() { 738 ++R; 739 ++OriginalR; 740 return *this; 741 } 742 }; 743 744 /// Return the original region for a captured region, if 745 /// one exists. It might return null. 746 const VarRegion *getOriginalRegion(const VarRegion *VR) const; 747 748 referenced_vars_iterator referenced_vars_begin() const; 749 referenced_vars_iterator referenced_vars_end() const; 750 751 void dumpToStream(raw_ostream &os) const override; 752 753 void Profile(llvm::FoldingSetNodeID& ID) const override; 754 755 static bool classof(const MemRegion* R) { 756 return R->getKind() == BlockDataRegionKind; 757 } 758 759 private: 760 void LazyInitializeReferencedVars(); 761 std::pair<const VarRegion *, const VarRegion *> 762 getCaptureRegions(const VarDecl *VD); 763 }; 764 765 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region 766 /// classes, SymbolicRegion represents a region that serves as an alias for 767 /// either a real region, a NULL pointer, etc. It essentially is used to 768 /// map the concept of symbolic values into the domain of regions. Symbolic 769 /// regions do not need to be typed. 770 class SymbolicRegion : public SubRegion { 771 friend class MemRegionManager; 772 773 const SymbolRef sym; 774 775 SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg) 776 : SubRegion(sreg, SymbolicRegionKind), sym(s) { 777 // Because pointer arithmetic is represented by ElementRegion layers, 778 // the base symbol here should not contain any arithmetic. 779 assert(s && isa<SymbolData>(s)); 780 assert(s->getType()->isAnyPointerType() || 781 s->getType()->isReferenceType() || 782 s->getType()->isBlockPointerType()); 783 assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) || 784 isa<GlobalSystemSpaceRegion>(sreg)); 785 } 786 787 public: 788 /// It might return null. 789 SymbolRef getSymbol() const { return sym; } 790 791 bool isBoundable() const override { return true; } 792 793 void Profile(llvm::FoldingSetNodeID& ID) const override; 794 795 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 796 SymbolRef sym, 797 const MemRegion* superRegion); 798 799 void dumpToStream(raw_ostream &os) const override; 800 801 static bool classof(const MemRegion* R) { 802 return R->getKind() == SymbolicRegionKind; 803 } 804 }; 805 806 /// StringRegion - Region associated with a StringLiteral. 807 class StringRegion : public TypedValueRegion { 808 friend class MemRegionManager; 809 810 const StringLiteral *Str; 811 812 StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg) 813 : TypedValueRegion(sreg, StringRegionKind), Str(str) { 814 assert(str); 815 } 816 817 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 818 const StringLiteral *Str, 819 const MemRegion *superRegion); 820 821 public: 822 LLVM_ATTRIBUTE_RETURNS_NONNULL 823 const StringLiteral *getStringLiteral() const { return Str; } 824 825 QualType getValueType() const override { return Str->getType(); } 826 827 bool isBoundable() const override { return false; } 828 829 void Profile(llvm::FoldingSetNodeID& ID) const override { 830 ProfileRegion(ID, Str, superRegion); 831 } 832 833 void dumpToStream(raw_ostream &os) const override; 834 835 static bool classof(const MemRegion* R) { 836 return R->getKind() == StringRegionKind; 837 } 838 }; 839 840 /// The region associated with an ObjCStringLiteral. 841 class ObjCStringRegion : public TypedValueRegion { 842 friend class MemRegionManager; 843 844 const ObjCStringLiteral *Str; 845 846 ObjCStringRegion(const ObjCStringLiteral *str, 847 const GlobalInternalSpaceRegion *sreg) 848 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) { 849 assert(str); 850 } 851 852 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 853 const ObjCStringLiteral *Str, 854 const MemRegion *superRegion); 855 856 public: 857 LLVM_ATTRIBUTE_RETURNS_NONNULL 858 const ObjCStringLiteral *getObjCStringLiteral() const { return Str; } 859 860 QualType getValueType() const override { return Str->getType(); } 861 862 bool isBoundable() const override { return false; } 863 864 void Profile(llvm::FoldingSetNodeID& ID) const override { 865 ProfileRegion(ID, Str, superRegion); 866 } 867 868 void dumpToStream(raw_ostream &os) const override; 869 870 static bool classof(const MemRegion* R) { 871 return R->getKind() == ObjCStringRegionKind; 872 } 873 }; 874 875 /// CompoundLiteralRegion - A memory region representing a compound literal. 876 /// Compound literals are essentially temporaries that are stack allocated 877 /// or in the global constant pool. 878 class CompoundLiteralRegion : public TypedValueRegion { 879 friend class MemRegionManager; 880 881 const CompoundLiteralExpr *CL; 882 883 CompoundLiteralRegion(const CompoundLiteralExpr *cl, 884 const MemSpaceRegion *sReg) 885 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) { 886 assert(cl); 887 assert(isa<GlobalInternalSpaceRegion>(sReg) || 888 isa<StackLocalsSpaceRegion>(sReg)); 889 } 890 891 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 892 const CompoundLiteralExpr *CL, 893 const MemRegion* superRegion); 894 895 public: 896 QualType getValueType() const override { return CL->getType(); } 897 898 bool isBoundable() const override { return !CL->isFileScope(); } 899 900 void Profile(llvm::FoldingSetNodeID& ID) const override; 901 902 void dumpToStream(raw_ostream &os) const override; 903 904 LLVM_ATTRIBUTE_RETURNS_NONNULL 905 const CompoundLiteralExpr *getLiteralExpr() const { return CL; } 906 907 static bool classof(const MemRegion* R) { 908 return R->getKind() == CompoundLiteralRegionKind; 909 } 910 }; 911 912 class DeclRegion : public TypedValueRegion { 913 protected: 914 DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) { 915 assert(classof(this)); 916 } 917 918 public: 919 // TODO what does this return? 920 virtual const ValueDecl *getDecl() const = 0; 921 922 static bool classof(const MemRegion* R) { 923 unsigned k = R->getKind(); 924 return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS; 925 } 926 }; 927 928 class VarRegion : public DeclRegion { 929 friend class MemRegionManager; 930 931 protected: 932 // Constructors and protected methods. 933 VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) { 934 // VarRegion appears in unknown space when it's a block variable as seen 935 // from a block using it, when this block is analyzed at top-level. 936 // Other block variables appear within block data regions, 937 // which, unlike everything else on this list, are not memory spaces. 938 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) || 939 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)); 940 } 941 942 public: 943 // TODO what does this return? 944 const VarDecl *getDecl() const override = 0; 945 946 /// It might return null. 947 const StackFrameContext *getStackFrame() const; 948 949 QualType getValueType() const override { 950 // FIXME: We can cache this if needed. 951 return getDecl()->getType(); 952 } 953 954 static bool classof(const MemRegion *R) { 955 unsigned k = R->getKind(); 956 return k >= BEGIN_VAR_REGIONS && k <= END_VAR_REGIONS; 957 } 958 }; 959 960 class NonParamVarRegion : public VarRegion { 961 friend class MemRegionManager; 962 963 const VarDecl *VD; 964 965 // Constructors and private methods. 966 NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg) 967 : VarRegion(sReg, NonParamVarRegionKind), VD(vd) { 968 // VarRegion appears in unknown space when it's a block variable as seen 969 // from a block using it, when this block is analyzed at top-level. 970 // Other block variables appear within block data regions, 971 // which, unlike everything else on this list, are not memory spaces. 972 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) || 973 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)); 974 assert(vd); 975 } 976 977 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD, 978 const MemRegion *superRegion); 979 980 public: 981 void Profile(llvm::FoldingSetNodeID &ID) const override; 982 983 LLVM_ATTRIBUTE_RETURNS_NONNULL 984 const VarDecl *getDecl() const override { return VD; } 985 986 QualType getValueType() const override { 987 // FIXME: We can cache this if needed. 988 return getDecl()->getType(); 989 } 990 991 void dumpToStream(raw_ostream &os) const override; 992 993 bool canPrintPrettyAsExpr() const override; 994 995 void printPrettyAsExpr(raw_ostream &os) const override; 996 997 static bool classof(const MemRegion* R) { 998 return R->getKind() == NonParamVarRegionKind; 999 } 1000 }; 1001 1002 /// ParamVarRegion - Represents a region for paremters. Only parameters of the 1003 /// function in the current stack frame are represented as `ParamVarRegion`s. 1004 /// Parameters of top-level analyzed functions as well as captured paremeters 1005 /// by lambdas and blocks are repesented as `VarRegion`s. 1006 1007 // FIXME: `ParamVarRegion` only supports parameters of functions, C++ 1008 // constructors, blocks and Objective-C methods with existing `Decl`. Upon 1009 // implementing stack frame creations for functions without decl (functions 1010 // passed by unknown function pointer) methods of `ParamVarRegion` must be 1011 // updated. 1012 class ParamVarRegion : public VarRegion { 1013 friend class MemRegionManager; 1014 1015 const Expr *OriginExpr; 1016 unsigned Index; 1017 1018 ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg) 1019 : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) { 1020 assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame()); 1021 assert(OriginExpr); 1022 } 1023 1024 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE, 1025 unsigned Idx, const MemRegion *SReg); 1026 1027 public: 1028 LLVM_ATTRIBUTE_RETURNS_NONNULL 1029 const Expr *getOriginExpr() const { return OriginExpr; } 1030 unsigned getIndex() const { return Index; } 1031 1032 void Profile(llvm::FoldingSetNodeID& ID) const override; 1033 1034 void dumpToStream(raw_ostream &os) const override; 1035 1036 QualType getValueType() const override; 1037 1038 /// TODO: What does this return? 1039 const ParmVarDecl *getDecl() const override; 1040 1041 bool canPrintPrettyAsExpr() const override; 1042 void printPrettyAsExpr(raw_ostream &os) const override; 1043 1044 static bool classof(const MemRegion *R) { 1045 return R->getKind() == ParamVarRegionKind; 1046 } 1047 }; 1048 1049 /// CXXThisRegion - Represents the region for the implicit 'this' parameter 1050 /// in a call to a C++ method. This region doesn't represent the object 1051 /// referred to by 'this', but rather 'this' itself. 1052 class CXXThisRegion : public TypedValueRegion { 1053 friend class MemRegionManager; 1054 1055 CXXThisRegion(const PointerType *thisPointerTy, 1056 const StackArgumentsSpaceRegion *sReg) 1057 : TypedValueRegion(sReg, CXXThisRegionKind), 1058 ThisPointerTy(thisPointerTy) { 1059 assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() && 1060 "Invalid region type!"); 1061 } 1062 1063 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 1064 const PointerType *PT, 1065 const MemRegion *sReg); 1066 1067 public: 1068 void Profile(llvm::FoldingSetNodeID &ID) const override; 1069 1070 QualType getValueType() const override { 1071 return QualType(ThisPointerTy, 0); 1072 } 1073 1074 void dumpToStream(raw_ostream &os) const override; 1075 1076 static bool classof(const MemRegion* R) { 1077 return R->getKind() == CXXThisRegionKind; 1078 } 1079 1080 private: 1081 const PointerType *ThisPointerTy; 1082 }; 1083 1084 class FieldRegion : public DeclRegion { 1085 friend class MemRegionManager; 1086 1087 const FieldDecl *FD; 1088 1089 FieldRegion(const FieldDecl *fd, const SubRegion *sReg) 1090 : DeclRegion(sReg, FieldRegionKind), FD(fd) { 1091 assert(FD); 1092 } 1093 1094 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD, 1095 const MemRegion* superRegion) { 1096 ID.AddInteger(static_cast<unsigned>(FieldRegionKind)); 1097 ID.AddPointer(FD); 1098 ID.AddPointer(superRegion); 1099 } 1100 1101 public: 1102 LLVM_ATTRIBUTE_RETURNS_NONNULL 1103 const FieldDecl *getDecl() const override { return FD; } 1104 1105 void Profile(llvm::FoldingSetNodeID &ID) const override; 1106 1107 QualType getValueType() const override { 1108 // FIXME: We can cache this if needed. 1109 return getDecl()->getType(); 1110 } 1111 1112 void dumpToStream(raw_ostream &os) const override; 1113 1114 bool canPrintPretty() const override; 1115 void printPretty(raw_ostream &os) const override; 1116 bool canPrintPrettyAsExpr() const override; 1117 void printPrettyAsExpr(raw_ostream &os) const override; 1118 1119 static bool classof(const MemRegion* R) { 1120 return R->getKind() == FieldRegionKind; 1121 } 1122 }; 1123 1124 class ObjCIvarRegion : public DeclRegion { 1125 friend class MemRegionManager; 1126 1127 const ObjCIvarDecl *IVD; 1128 1129 ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg); 1130 1131 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, 1132 const MemRegion* superRegion); 1133 1134 public: 1135 LLVM_ATTRIBUTE_RETURNS_NONNULL 1136 const ObjCIvarDecl *getDecl() const override; 1137 1138 void Profile(llvm::FoldingSetNodeID& ID) const override; 1139 1140 QualType getValueType() const override; 1141 1142 bool canPrintPrettyAsExpr() const override; 1143 void printPrettyAsExpr(raw_ostream &os) const override; 1144 1145 void dumpToStream(raw_ostream &os) const override; 1146 1147 static bool classof(const MemRegion* R) { 1148 return R->getKind() == ObjCIvarRegionKind; 1149 } 1150 }; 1151 1152 //===----------------------------------------------------------------------===// 1153 // Auxiliary data classes for use with MemRegions. 1154 //===----------------------------------------------------------------------===// 1155 1156 class RegionRawOffset { 1157 friend class ElementRegion; 1158 1159 const MemRegion *Region; 1160 CharUnits Offset; 1161 1162 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) 1163 : Region(reg), Offset(offset) {} 1164 1165 public: 1166 // FIXME: Eventually support symbolic offsets. 1167 CharUnits getOffset() const { return Offset; } 1168 1169 // It might return null. 1170 const MemRegion *getRegion() const { return Region; } 1171 1172 void dumpToStream(raw_ostream &os) const; 1173 void dump() const; 1174 }; 1175 1176 /// ElementRegion is used to represent both array elements and casts. 1177 class ElementRegion : public TypedValueRegion { 1178 friend class MemRegionManager; 1179 1180 QualType ElementType; 1181 NonLoc Index; 1182 1183 ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg) 1184 : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType), 1185 Index(Idx) { 1186 assert((!isa<nonloc::ConcreteInt>(Idx) || 1187 Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && 1188 "The index must be signed"); 1189 assert(!elementType.isNull() && !elementType->isVoidType() && 1190 "Invalid region type!"); 1191 } 1192 1193 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 1194 SVal Idx, const MemRegion* superRegion); 1195 1196 public: 1197 NonLoc getIndex() const { return Index; } 1198 1199 QualType getValueType() const override { return ElementType; } 1200 1201 QualType getElementType() const { return ElementType; } 1202 1203 /// Compute the offset within the array. The array might also be a subobject. 1204 RegionRawOffset getAsArrayOffset() const; 1205 1206 void dumpToStream(raw_ostream &os) const override; 1207 1208 void Profile(llvm::FoldingSetNodeID& ID) const override; 1209 1210 static bool classof(const MemRegion* R) { 1211 return R->getKind() == ElementRegionKind; 1212 } 1213 }; 1214 1215 // C++ temporary object associated with an expression. 1216 class CXXTempObjectRegion : public TypedValueRegion { 1217 friend class MemRegionManager; 1218 1219 Expr const *Ex; 1220 1221 CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg) 1222 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) { 1223 assert(E); 1224 assert(isa<StackLocalsSpaceRegion>(sReg) || 1225 isa<GlobalInternalSpaceRegion>(sReg)); 1226 } 1227 1228 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 1229 Expr const *E, const MemRegion *sReg); 1230 1231 public: 1232 LLVM_ATTRIBUTE_RETURNS_NONNULL 1233 const Expr *getExpr() const { return Ex; } 1234 1235 QualType getValueType() const override { return Ex->getType(); } 1236 1237 void dumpToStream(raw_ostream &os) const override; 1238 1239 void Profile(llvm::FoldingSetNodeID &ID) const override; 1240 1241 static bool classof(const MemRegion* R) { 1242 return R->getKind() == CXXTempObjectRegionKind; 1243 } 1244 }; 1245 1246 // CXXBaseObjectRegion represents a base object within a C++ object. It is 1247 // identified by the base class declaration and the region of its parent object. 1248 class CXXBaseObjectRegion : public TypedValueRegion { 1249 friend class MemRegionManager; 1250 1251 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data; 1252 1253 CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual, 1254 const SubRegion *SReg) 1255 : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) { 1256 assert(RD); 1257 } 1258 1259 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, 1260 bool IsVirtual, const MemRegion *SReg); 1261 1262 public: 1263 LLVM_ATTRIBUTE_RETURNS_NONNULL 1264 const CXXRecordDecl *getDecl() const { return Data.getPointer(); } 1265 bool isVirtual() const { return Data.getInt(); } 1266 1267 QualType getValueType() const override; 1268 1269 void dumpToStream(raw_ostream &os) const override; 1270 1271 void Profile(llvm::FoldingSetNodeID &ID) const override; 1272 1273 bool canPrintPrettyAsExpr() const override; 1274 1275 void printPrettyAsExpr(raw_ostream &os) const override; 1276 1277 static bool classof(const MemRegion *region) { 1278 return region->getKind() == CXXBaseObjectRegionKind; 1279 } 1280 }; 1281 1282 // CXXDerivedObjectRegion represents a derived-class object that surrounds 1283 // a C++ object. It is identified by the derived class declaration and the 1284 // region of its parent object. It is a bit counter-intuitive (but not otherwise 1285 // unseen) that this region represents a larger segment of memory that its 1286 // super-region. 1287 class CXXDerivedObjectRegion : public TypedValueRegion { 1288 friend class MemRegionManager; 1289 1290 const CXXRecordDecl *DerivedD; 1291 1292 CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg) 1293 : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) { 1294 assert(DerivedD); 1295 // In case of a concrete region, it should always be possible to model 1296 // the base-to-derived cast by undoing a previous derived-to-base cast, 1297 // otherwise the cast is most likely ill-formed. 1298 assert(SReg->getSymbolicBase() && 1299 "Should have unwrapped a base region instead!"); 1300 } 1301 1302 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, 1303 const MemRegion *SReg); 1304 1305 public: 1306 LLVM_ATTRIBUTE_RETURNS_NONNULL 1307 const CXXRecordDecl *getDecl() const { return DerivedD; } 1308 1309 QualType getValueType() const override; 1310 1311 void dumpToStream(raw_ostream &os) const override; 1312 1313 void Profile(llvm::FoldingSetNodeID &ID) const override; 1314 1315 bool canPrintPrettyAsExpr() const override; 1316 1317 void printPrettyAsExpr(raw_ostream &os) const override; 1318 1319 static bool classof(const MemRegion *region) { 1320 return region->getKind() == CXXDerivedObjectRegionKind; 1321 } 1322 }; 1323 1324 template<typename RegionTy> 1325 const RegionTy* MemRegion::getAs() const { 1326 if (const auto *RT = dyn_cast<RegionTy>(this)) 1327 return RT; 1328 1329 return nullptr; 1330 } 1331 1332 template <typename RegionTy> 1333 LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const { 1334 return cast<RegionTy>(this); 1335 } 1336 1337 //===----------------------------------------------------------------------===// 1338 // MemRegionManager - Factory object for creating regions. 1339 //===----------------------------------------------------------------------===// 1340 1341 class MemRegionManager { 1342 ASTContext &Ctx; 1343 llvm::BumpPtrAllocator& A; 1344 1345 llvm::FoldingSet<MemRegion> Regions; 1346 1347 GlobalInternalSpaceRegion *InternalGlobals = nullptr; 1348 GlobalSystemSpaceRegion *SystemGlobals = nullptr; 1349 GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr; 1350 1351 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 1352 StackLocalsSpaceRegions; 1353 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> 1354 StackArgumentsSpaceRegions; 1355 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> 1356 StaticsGlobalSpaceRegions; 1357 1358 HeapSpaceRegion *heap = nullptr; 1359 UnknownSpaceRegion *unknown = nullptr; 1360 CodeSpaceRegion *code = nullptr; 1361 1362 public: 1363 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {} 1364 ~MemRegionManager(); 1365 1366 ASTContext &getContext() { return Ctx; } 1367 const ASTContext &getContext() const { return Ctx; } 1368 1369 llvm::BumpPtrAllocator &getAllocator() { return A; } 1370 1371 /// \returns The static size in bytes of the region \p MR. 1372 /// \note The region \p MR must be a 'SubRegion'. 1373 DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, 1374 SValBuilder &SVB) const; 1375 1376 /// getStackLocalsRegion - Retrieve the memory region associated with the 1377 /// specified stack frame. 1378 const StackLocalsSpaceRegion * 1379 getStackLocalsRegion(const StackFrameContext *STC); 1380 1381 /// getStackArgumentsRegion - Retrieve the memory region associated with 1382 /// function/method arguments of the specified stack frame. 1383 const StackArgumentsSpaceRegion * 1384 getStackArgumentsRegion(const StackFrameContext *STC); 1385 1386 /// getGlobalsRegion - Retrieve the memory region associated with 1387 /// global variables. 1388 const GlobalsSpaceRegion *getGlobalsRegion( 1389 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 1390 const CodeTextRegion *R = nullptr); 1391 1392 /// getHeapRegion - Retrieve the memory region associated with the 1393 /// generic "heap". 1394 const HeapSpaceRegion *getHeapRegion(); 1395 1396 /// getUnknownRegion - Retrieve the memory region associated with unknown 1397 /// memory space. 1398 const UnknownSpaceRegion *getUnknownRegion(); 1399 1400 const CodeSpaceRegion *getCodeRegion(); 1401 1402 /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 1403 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 1404 const LocationContext *LC); 1405 1406 /// getCompoundLiteralRegion - Retrieve the region associated with a 1407 /// given CompoundLiteral. 1408 const CompoundLiteralRegion* 1409 getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1410 const LocationContext *LC); 1411 1412 /// getCXXThisRegion - Retrieve the [artificial] region associated with the 1413 /// parameter 'this'. 1414 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 1415 const LocationContext *LC); 1416 1417 /// Retrieve or create a "symbolic" memory region. 1418 /// If no memory space is specified, `UnknownSpaceRegion` will be used. 1419 const SymbolicRegion * 1420 getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr); 1421 1422 /// Return a unique symbolic region belonging to heap memory space. 1423 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym); 1424 1425 const StringRegion *getStringRegion(const StringLiteral *Str); 1426 1427 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 1428 1429 /// getVarRegion - Retrieve or create the memory region associated with 1430 /// a specified VarDecl and LocationContext. 1431 const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC); 1432 1433 /// getVarRegion - Retrieve or create the memory region associated with 1434 /// a specified VarDecl and LocationContext. 1435 const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD, 1436 const MemRegion *superR); 1437 1438 /// getParamVarRegion - Retrieve or create the memory region 1439 /// associated with a specified CallExpr, Index and LocationContext. 1440 const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr, 1441 unsigned Index, 1442 const LocationContext *LC); 1443 1444 /// getElementRegion - Retrieve the memory region associated with the 1445 /// associated element type, index, and super region. 1446 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 1447 const SubRegion *superRegion, 1448 ASTContext &Ctx); 1449 1450 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 1451 const SubRegion *superRegion) { 1452 return getElementRegion(ER->getElementType(), ER->getIndex(), 1453 superRegion, ER->getContext()); 1454 } 1455 1456 /// getFieldRegion - Retrieve or create the memory region associated with 1457 /// a specified FieldDecl. 'superRegion' corresponds to the containing 1458 /// memory region (which typically represents the memory representing 1459 /// a structure or class). 1460 const FieldRegion *getFieldRegion(const FieldDecl *fd, 1461 const SubRegion* superRegion); 1462 1463 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 1464 const SubRegion *superRegion) { 1465 return getFieldRegion(FR->getDecl(), superRegion); 1466 } 1467 1468 /// getObjCIvarRegion - Retrieve or create the memory region associated with 1469 /// a specified Objective-c instance variable. 'superRegion' corresponds 1470 /// to the containing region (which typically represents the Objective-C 1471 /// object). 1472 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 1473 const SubRegion* superRegion); 1474 1475 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 1476 LocationContext const *LC); 1477 1478 /// Create a CXXBaseObjectRegion with the given base class for region 1479 /// \p Super. 1480 /// 1481 /// The type of \p Super is assumed be a class deriving from \p BaseClass. 1482 const CXXBaseObjectRegion * 1483 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super, 1484 bool IsVirtual); 1485 1486 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 1487 /// super region. 1488 const CXXBaseObjectRegion * 1489 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 1490 const SubRegion *superRegion) { 1491 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion, 1492 baseReg->isVirtual()); 1493 } 1494 1495 /// Create a CXXDerivedObjectRegion with the given derived class for region 1496 /// \p Super. This should not be used for casting an existing 1497 /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion 1498 /// should be removed. 1499 const CXXDerivedObjectRegion * 1500 getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass, 1501 const SubRegion *Super); 1502 1503 const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD); 1504 const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD, 1505 CanQualType locTy, 1506 AnalysisDeclContext *AC); 1507 1508 /// getBlockDataRegion - Get the memory region associated with an instance 1509 /// of a block. Unlike many other MemRegions, the LocationContext* 1510 /// argument is allowed to be NULL for cases where we have no known 1511 /// context. 1512 const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc, 1513 const LocationContext *lc, 1514 unsigned blockCount); 1515 1516 /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended 1517 /// by static references. This differs from getCXXTempObjectRegion in the 1518 /// super-region used. 1519 const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex); 1520 1521 private: 1522 template <typename RegionTy, typename SuperTy, 1523 typename Arg1Ty> 1524 RegionTy* getSubRegion(const Arg1Ty arg1, 1525 const SuperTy* superRegion); 1526 1527 template <typename RegionTy, typename SuperTy, 1528 typename Arg1Ty, typename Arg2Ty> 1529 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, 1530 const SuperTy* superRegion); 1531 1532 template <typename RegionTy, typename SuperTy, 1533 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty> 1534 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, 1535 const Arg3Ty arg3, 1536 const SuperTy* superRegion); 1537 1538 template <typename REG> 1539 const REG* LazyAllocate(REG*& region); 1540 1541 template <typename REG, typename ARG> 1542 const REG* LazyAllocate(REG*& region, ARG a); 1543 }; 1544 1545 //===----------------------------------------------------------------------===// 1546 // Out-of-line member definitions. 1547 //===----------------------------------------------------------------------===// 1548 1549 inline ASTContext &MemRegion::getContext() const { 1550 return getMemRegionManager().getContext(); 1551 } 1552 1553 //===----------------------------------------------------------------------===// 1554 // Means for storing region/symbol handling traits. 1555 //===----------------------------------------------------------------------===// 1556 1557 /// Information about invalidation for a particular region/symbol. 1558 class RegionAndSymbolInvalidationTraits { 1559 using StorageTypeForKinds = unsigned char; 1560 1561 llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap; 1562 llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap; 1563 1564 using const_region_iterator = 1565 llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator; 1566 using const_symbol_iterator = 1567 llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator; 1568 1569 public: 1570 /// Describes different invalidation traits. 1571 enum InvalidationKinds { 1572 /// Tells that a region's contents is not changed. 1573 TK_PreserveContents = 0x1, 1574 1575 /// Suppress pointer-escaping of a region. 1576 TK_SuppressEscape = 0x2, 1577 1578 // Do not invalidate super region. 1579 TK_DoNotInvalidateSuperRegion = 0x4, 1580 1581 /// When applied to a MemSpaceRegion, indicates the entire memory space 1582 /// should be invalidated. 1583 TK_EntireMemSpace = 0x8 1584 1585 // Do not forget to extend StorageTypeForKinds if number of traits exceed 1586 // the number of bits StorageTypeForKinds can store. 1587 }; 1588 1589 void setTrait(SymbolRef Sym, InvalidationKinds IK); 1590 void setTrait(const MemRegion *MR, InvalidationKinds IK); 1591 bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const; 1592 bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const; 1593 }; 1594 1595 //===----------------------------------------------------------------------===// 1596 // Pretty-printing regions. 1597 //===----------------------------------------------------------------------===// 1598 inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) { 1599 R->dumpToStream(os); 1600 return os; 1601 } 1602 1603 } // namespace ento 1604 1605 } // namespace clang 1606 1607 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H 1608