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