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