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