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