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