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