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/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/ErrorHandling.h" 27 #include <string> 28 29 namespace llvm { 30 class BumpPtrAllocator; 31 } 32 33 namespace clang { 34 35 class LocationContext; 36 class StackFrameContext; 37 38 namespace ento { 39 40 class CodeTextRegion; 41 class MemRegionManager; 42 class MemSpaceRegion; 43 class SValBuilder; 44 class SymbolicRegion; 45 class VarRegion; 46 47 /// Represent a region's offset within the top level base region. 48 class RegionOffset { 49 /// The base region. 50 const MemRegion *R; 51 52 /// The bit offset within the base region. It shouldn't be negative. 53 int64_t Offset; 54 55 public: 56 // We're using a const instead of an enumeration due to the size required; 57 // Visual Studio will only create enumerations of size int, not long long. 58 static const int64_t Symbolic = INT64_MAX; 59 60 RegionOffset() : R(0) {} 61 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} 62 63 const MemRegion *getRegion() const { return R; } 64 65 bool hasSymbolicOffset() const { return Offset == Symbolic; } 66 67 int64_t getOffset() const { 68 assert(!hasSymbolicOffset()); 69 return Offset; 70 } 71 72 bool isValid() const { return R; } 73 }; 74 75 //===----------------------------------------------------------------------===// 76 // Base region classes. 77 //===----------------------------------------------------------------------===// 78 79 /// MemRegion - The root abstract class for all memory regions. 80 class MemRegion : public llvm::FoldingSetNode { 81 friend class MemRegionManager; 82 public: 83 enum Kind { 84 // Memory spaces. 85 GenericMemSpaceRegionKind, 86 StackLocalsSpaceRegionKind, 87 StackArgumentsSpaceRegionKind, 88 HeapSpaceRegionKind, 89 UnknownSpaceRegionKind, 90 StaticGlobalSpaceRegionKind, 91 GlobalInternalSpaceRegionKind, 92 GlobalSystemSpaceRegionKind, 93 GlobalImmutableSpaceRegionKind, 94 BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind, 95 END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 96 BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind, 97 END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 98 BEG_MEMSPACES = GenericMemSpaceRegionKind, 99 END_MEMSPACES = GlobalImmutableSpaceRegionKind, 100 // Untyped regions. 101 SymbolicRegionKind, 102 AllocaRegionKind, 103 // Typed regions. 104 BEG_TYPED_REGIONS, 105 FunctionTextRegionKind = BEG_TYPED_REGIONS, 106 BlockTextRegionKind, 107 BlockDataRegionKind, 108 BEG_TYPED_VALUE_REGIONS, 109 CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS, 110 CXXThisRegionKind, 111 StringRegionKind, 112 ObjCStringRegionKind, 113 ElementRegionKind, 114 // Decl Regions. 115 BEG_DECL_REGIONS, 116 VarRegionKind = BEG_DECL_REGIONS, 117 FieldRegionKind, 118 ObjCIvarRegionKind, 119 END_DECL_REGIONS = ObjCIvarRegionKind, 120 CXXTempObjectRegionKind, 121 CXXBaseObjectRegionKind, 122 END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind, 123 END_TYPED_REGIONS = CXXBaseObjectRegionKind 124 }; 125 126 private: 127 const Kind kind; 128 129 protected: 130 MemRegion(Kind k) : kind(k) {} 131 virtual ~MemRegion(); 132 133 public: 134 ASTContext &getContext() const; 135 136 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 137 138 virtual MemRegionManager* getMemRegionManager() const = 0; 139 140 const MemSpaceRegion *getMemorySpace() const; 141 142 const MemRegion *getBaseRegion() const; 143 144 /// Check if the region is a subregion of the given region. 145 virtual bool isSubRegionOf(const MemRegion *R) const; 146 147 const MemRegion *StripCasts(bool StripBaseCasts = true) const; 148 149 /// \brief If this is a symbolic region, returns the region. Otherwise, 150 /// goes up the base chain looking for the first symbolic base region. 151 const SymbolicRegion *getSymbolicBase() const; 152 153 bool hasGlobalsOrParametersStorage() const; 154 155 bool hasStackStorage() const; 156 157 bool hasStackNonParametersStorage() const; 158 159 bool hasStackParametersStorage() const; 160 161 /// Compute the offset within the top level memory object. 162 RegionOffset getAsOffset() const; 163 164 /// \brief Get a string representation of a region for debug use. 165 std::string getString() const; 166 167 virtual void dumpToStream(raw_ostream &os) const; 168 169 void dump() const; 170 171 /// \brief Returns true if this region can be printed in a user-friendly way. 172 virtual bool canPrintPretty() const; 173 174 /// \brief Print the region for use in diagnostics. 175 virtual void printPretty(raw_ostream &os) const; 176 177 /// \brief Returns true if this region's textual representation can be used 178 /// as part of a larger expression. 179 virtual bool canPrintPrettyAsExpr() const; 180 181 /// \brief Print the region as expression. 182 /// 183 /// When this region represents a subexpression, the method is for printing 184 /// an expression containing it. 185 virtual void printPrettyAsExpr(raw_ostream &os) const; 186 187 Kind getKind() const { return kind; } 188 189 template<typename RegionTy> const RegionTy* getAs() const; 190 191 virtual bool isBoundable() const { return false; } 192 }; 193 194 /// MemSpaceRegion - A memory region that represents a "memory space"; 195 /// for example, the set of global variables, the stack frame, etc. 196 class MemSpaceRegion : public MemRegion { 197 protected: 198 friend class MemRegionManager; 199 200 MemRegionManager *Mgr; 201 202 MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind) 203 : MemRegion(k), Mgr(mgr) { 204 assert(classof(this)); 205 } 206 207 MemRegionManager* getMemRegionManager() const { return Mgr; } 208 209 public: 210 bool isBoundable() const { return false; } 211 212 void Profile(llvm::FoldingSetNodeID &ID) const; 213 214 static bool classof(const MemRegion *R) { 215 Kind k = R->getKind(); 216 return k >= BEG_MEMSPACES && k <= END_MEMSPACES; 217 } 218 }; 219 220 class GlobalsSpaceRegion : public MemSpaceRegion { 221 virtual void anchor(); 222 protected: 223 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) 224 : MemSpaceRegion(mgr, k) {} 225 public: 226 static bool classof(const MemRegion *R) { 227 Kind k = R->getKind(); 228 return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; 229 } 230 }; 231 232 /// \brief The region of the static variables within the current CodeTextRegion 233 /// scope. 234 /// 235 /// Currently, only the static locals are placed there, so we know that these 236 /// variables do not get invalidated by calls to other functions. 237 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { 238 friend class MemRegionManager; 239 240 const CodeTextRegion *CR; 241 242 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) 243 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {} 244 245 public: 246 void Profile(llvm::FoldingSetNodeID &ID) const; 247 248 void dumpToStream(raw_ostream &os) const; 249 250 const CodeTextRegion *getCodeRegion() const { return CR; } 251 252 static bool classof(const MemRegion *R) { 253 return R->getKind() == StaticGlobalSpaceRegionKind; 254 } 255 }; 256 257 /// \brief The region for all the non-static global variables. 258 /// 259 /// This class is further split into subclasses for efficient implementation of 260 /// invalidating a set of related global values as is done in 261 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent 262 /// globals, we invalidate the whole parent region). 263 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { 264 friend class MemRegionManager; 265 266 protected: 267 NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) 268 : GlobalsSpaceRegion(mgr, k) {} 269 270 public: 271 272 static bool classof(const MemRegion *R) { 273 Kind k = R->getKind(); 274 return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES && 275 k <= END_NON_STATIC_GLOBAL_MEMSPACES; 276 } 277 }; 278 279 /// \brief The region containing globals which are defined in system/external 280 /// headers and are considered modifiable by system calls (ex: errno). 281 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { 282 friend class MemRegionManager; 283 284 GlobalSystemSpaceRegion(MemRegionManager *mgr) 285 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} 286 287 public: 288 289 void dumpToStream(raw_ostream &os) const; 290 291 static bool classof(const MemRegion *R) { 292 return R->getKind() == GlobalSystemSpaceRegionKind; 293 } 294 }; 295 296 /// \brief The region containing globals which are considered not to be modified 297 /// or point to data which could be modified as a result of a function call 298 /// (system or internal). Ex: Const global scalars would be modeled as part of 299 /// this region. This region also includes most system globals since they have 300 /// low chance of being modified. 301 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { 302 friend class MemRegionManager; 303 304 GlobalImmutableSpaceRegion(MemRegionManager *mgr) 305 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} 306 307 public: 308 309 void dumpToStream(raw_ostream &os) const; 310 311 static bool classof(const MemRegion *R) { 312 return R->getKind() == GlobalImmutableSpaceRegionKind; 313 } 314 }; 315 316 /// \brief The region containing globals which can be modified by calls to 317 /// "internally" defined functions - (for now just) functions other then system 318 /// calls. 319 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { 320 friend class MemRegionManager; 321 322 GlobalInternalSpaceRegion(MemRegionManager *mgr) 323 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} 324 325 public: 326 327 void dumpToStream(raw_ostream &os) const; 328 329 static bool classof(const MemRegion *R) { 330 return R->getKind() == GlobalInternalSpaceRegionKind; 331 } 332 }; 333 334 class HeapSpaceRegion : public MemSpaceRegion { 335 virtual void anchor(); 336 friend class MemRegionManager; 337 338 HeapSpaceRegion(MemRegionManager *mgr) 339 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} 340 public: 341 342 void dumpToStream(raw_ostream &os) const; 343 344 static bool classof(const MemRegion *R) { 345 return R->getKind() == HeapSpaceRegionKind; 346 } 347 }; 348 349 class UnknownSpaceRegion : public MemSpaceRegion { 350 virtual void anchor(); 351 friend class MemRegionManager; 352 UnknownSpaceRegion(MemRegionManager *mgr) 353 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} 354 public: 355 356 void dumpToStream(raw_ostream &os) const; 357 358 static bool classof(const MemRegion *R) { 359 return R->getKind() == UnknownSpaceRegionKind; 360 } 361 }; 362 363 class StackSpaceRegion : public MemSpaceRegion { 364 private: 365 const StackFrameContext *SFC; 366 367 protected: 368 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) 369 : MemSpaceRegion(mgr, k), SFC(sfc) { 370 assert(classof(this)); 371 } 372 373 public: 374 const StackFrameContext *getStackFrame() const { return SFC; } 375 376 void Profile(llvm::FoldingSetNodeID &ID) const; 377 378 static bool classof(const MemRegion *R) { 379 Kind k = R->getKind(); 380 return k >= StackLocalsSpaceRegionKind && 381 k <= StackArgumentsSpaceRegionKind; 382 } 383 }; 384 385 class StackLocalsSpaceRegion : public StackSpaceRegion { 386 virtual void anchor(); 387 friend class MemRegionManager; 388 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 389 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} 390 public: 391 392 void dumpToStream(raw_ostream &os) const; 393 394 static bool classof(const MemRegion *R) { 395 return R->getKind() == StackLocalsSpaceRegionKind; 396 } 397 }; 398 399 class StackArgumentsSpaceRegion : public StackSpaceRegion { 400 private: 401 virtual void anchor(); 402 friend class MemRegionManager; 403 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 404 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} 405 public: 406 407 void dumpToStream(raw_ostream &os) const; 408 409 static bool classof(const MemRegion *R) { 410 return R->getKind() == StackArgumentsSpaceRegionKind; 411 } 412 }; 413 414 415 /// SubRegion - A region that subsets another larger region. Most regions 416 /// are subclasses of SubRegion. 417 class SubRegion : public MemRegion { 418 private: 419 virtual void anchor(); 420 protected: 421 const MemRegion* superRegion; 422 SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} 423 public: 424 const MemRegion* getSuperRegion() const { 425 return superRegion; 426 } 427 428 /// getExtent - Returns the size of the region in bytes. 429 virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { 430 return UnknownVal(); 431 } 432 433 MemRegionManager* getMemRegionManager() const; 434 435 virtual bool isSubRegionOf(const MemRegion* R) const; 436 437 static bool classof(const MemRegion* R) { 438 return R->getKind() > END_MEMSPACES; 439 } 440 }; 441 442 //===----------------------------------------------------------------------===// 443 // MemRegion subclasses. 444 //===----------------------------------------------------------------------===// 445 446 /// AllocaRegion - A region that represents an untyped blob of bytes created 447 /// by a call to 'alloca'. 448 class AllocaRegion : public SubRegion { 449 friend class MemRegionManager; 450 protected: 451 unsigned Cnt; // Block counter. Used to distinguish different pieces of 452 // memory allocated by alloca at the same call site. 453 const Expr *Ex; 454 455 AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion) 456 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} 457 458 public: 459 460 const Expr *getExpr() const { return Ex; } 461 462 bool isBoundable() const { return true; } 463 464 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 465 466 void Profile(llvm::FoldingSetNodeID& ID) const; 467 468 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, 469 unsigned Cnt, const MemRegion *superRegion); 470 471 void dumpToStream(raw_ostream &os) const; 472 473 static bool classof(const MemRegion* R) { 474 return R->getKind() == AllocaRegionKind; 475 } 476 }; 477 478 /// TypedRegion - An abstract class representing regions that are typed. 479 class TypedRegion : public SubRegion { 480 public: 481 virtual void anchor(); 482 protected: 483 TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} 484 485 public: 486 virtual QualType getLocationType() const = 0; 487 488 QualType getDesugaredLocationType(ASTContext &Context) const { 489 return getLocationType().getDesugaredType(Context); 490 } 491 492 bool isBoundable() const { return true; } 493 494 static bool classof(const MemRegion* R) { 495 unsigned k = R->getKind(); 496 return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; 497 } 498 }; 499 500 /// TypedValueRegion - An abstract class representing regions having a typed value. 501 class TypedValueRegion : public TypedRegion { 502 public: 503 virtual void anchor(); 504 protected: 505 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {} 506 507 public: 508 virtual QualType getValueType() const = 0; 509 510 virtual QualType getLocationType() const { 511 // FIXME: We can possibly optimize this later to cache this value. 512 QualType T = getValueType(); 513 ASTContext &ctx = getContext(); 514 if (T->getAs<ObjCObjectType>()) 515 return ctx.getObjCObjectPointerType(T); 516 return ctx.getPointerType(getValueType()); 517 } 518 519 QualType getDesugaredValueType(ASTContext &Context) const { 520 QualType T = getValueType(); 521 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; 522 } 523 524 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 525 526 static bool classof(const MemRegion* R) { 527 unsigned k = R->getKind(); 528 return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; 529 } 530 }; 531 532 533 class CodeTextRegion : public TypedRegion { 534 public: 535 virtual void anchor(); 536 protected: 537 CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} 538 public: 539 bool isBoundable() const { return false; } 540 541 static bool classof(const MemRegion* R) { 542 Kind k = R->getKind(); 543 return k >= FunctionTextRegionKind && k <= BlockTextRegionKind; 544 } 545 }; 546 547 /// FunctionTextRegion - A region that represents code texts of function. 548 class FunctionTextRegion : public CodeTextRegion { 549 const NamedDecl *FD; 550 public: 551 FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg) 552 : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) { 553 assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)); 554 } 555 556 QualType getLocationType() const { 557 const ASTContext &Ctx = getContext(); 558 if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) { 559 return Ctx.getPointerType(D->getType()); 560 } 561 562 assert(isa<ObjCMethodDecl>(FD)); 563 assert(false && "Getting the type of ObjCMethod is not supported yet"); 564 565 // TODO: We might want to return a different type here (ex: id (*ty)(...)) 566 // depending on how it is used. 567 return QualType(); 568 } 569 570 const NamedDecl *getDecl() const { 571 return FD; 572 } 573 574 virtual void dumpToStream(raw_ostream &os) const; 575 576 void Profile(llvm::FoldingSetNodeID& ID) const; 577 578 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, 579 const MemRegion*); 580 581 static bool classof(const MemRegion* R) { 582 return R->getKind() == FunctionTextRegionKind; 583 } 584 }; 585 586 587 /// BlockTextRegion - A region that represents code texts of blocks (closures). 588 /// Blocks are represented with two kinds of regions. BlockTextRegions 589 /// represent the "code", while BlockDataRegions represent instances of blocks, 590 /// which correspond to "code+data". The distinction is important, because 591 /// like a closure a block captures the values of externally referenced 592 /// variables. 593 class BlockTextRegion : public CodeTextRegion { 594 friend class MemRegionManager; 595 596 const BlockDecl *BD; 597 AnalysisDeclContext *AC; 598 CanQualType locTy; 599 600 BlockTextRegion(const BlockDecl *bd, CanQualType lTy, 601 AnalysisDeclContext *ac, const MemRegion* sreg) 602 : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {} 603 604 public: 605 QualType getLocationType() const { 606 return locTy; 607 } 608 609 const BlockDecl *getDecl() const { 610 return BD; 611 } 612 613 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } 614 615 virtual void dumpToStream(raw_ostream &os) const; 616 617 void Profile(llvm::FoldingSetNodeID& ID) const; 618 619 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, 620 CanQualType, const AnalysisDeclContext*, 621 const MemRegion*); 622 623 static bool classof(const MemRegion* R) { 624 return R->getKind() == BlockTextRegionKind; 625 } 626 }; 627 628 /// BlockDataRegion - A region that represents a block instance. 629 /// Blocks are represented with two kinds of regions. BlockTextRegions 630 /// represent the "code", while BlockDataRegions represent instances of blocks, 631 /// which correspond to "code+data". The distinction is important, because 632 /// like a closure a block captures the values of externally referenced 633 /// variables. 634 class BlockDataRegion : public TypedRegion { 635 friend class MemRegionManager; 636 const BlockTextRegion *BC; 637 const LocationContext *LC; // Can be null */ 638 void *ReferencedVars; 639 void *OriginalVars; 640 641 BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, 642 const MemRegion *sreg) 643 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), 644 ReferencedVars(0), OriginalVars(0) {} 645 646 public: 647 const BlockTextRegion *getCodeRegion() const { return BC; } 648 649 const BlockDecl *getDecl() const { return BC->getDecl(); } 650 651 QualType getLocationType() const { return BC->getLocationType(); } 652 653 class referenced_vars_iterator { 654 const MemRegion * const *R; 655 const MemRegion * const *OriginalR; 656 public: 657 explicit referenced_vars_iterator(const MemRegion * const *r, 658 const MemRegion * const *originalR) 659 : R(r), OriginalR(originalR) {} 660 661 const VarRegion *getCapturedRegion() const { 662 return cast<VarRegion>(*R); 663 } 664 const VarRegion *getOriginalRegion() const { 665 return cast<VarRegion>(*OriginalR); 666 } 667 668 bool operator==(const referenced_vars_iterator &I) const { 669 assert((R == 0) == (I.R == 0)); 670 return I.R == R; 671 } 672 bool operator!=(const referenced_vars_iterator &I) const { 673 assert((R == 0) == (I.R == 0)); 674 return I.R != R; 675 } 676 referenced_vars_iterator &operator++() { 677 ++R; 678 ++OriginalR; 679 return *this; 680 } 681 }; 682 683 /// Return the original region for a captured region, if 684 /// one exists. 685 const VarRegion *getOriginalRegion(const VarRegion *VR) const; 686 687 referenced_vars_iterator referenced_vars_begin() const; 688 referenced_vars_iterator referenced_vars_end() const; 689 690 virtual void dumpToStream(raw_ostream &os) const; 691 692 void Profile(llvm::FoldingSetNodeID& ID) const; 693 694 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, 695 const LocationContext *, 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 /// clases, 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 { return true; } 724 725 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 726 727 void Profile(llvm::FoldingSetNodeID& ID) const; 728 729 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 730 SymbolRef sym, 731 const MemRegion* superRegion); 732 733 void dumpToStream(raw_ostream &os) const; 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 { 758 return Str->getType(); 759 } 760 761 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 762 763 bool isBoundable() const { return false; } 764 765 void Profile(llvm::FoldingSetNodeID& ID) const { 766 ProfileRegion(ID, Str, superRegion); 767 } 768 769 void dumpToStream(raw_ostream &os) const; 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 { 794 return Str->getType(); 795 } 796 797 bool isBoundable() const { return false; } 798 799 void Profile(llvm::FoldingSetNodeID& ID) const { 800 ProfileRegion(ID, Str, superRegion); 801 } 802 803 void dumpToStream(raw_ostream &os) const; 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 { 826 return CL->getType(); 827 } 828 829 bool isBoundable() const { return !CL->isFileScope(); } 830 831 void Profile(llvm::FoldingSetNodeID& ID) const; 832 833 void dumpToStream(raw_ostream &os) const; 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; 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; 875 876 public: 877 const VarDecl *getDecl() const { return cast<VarDecl>(D); } 878 879 const StackFrameContext *getStackFrame() const; 880 881 QualType getValueType() const { 882 // FIXME: We can cache this if needed. 883 return getDecl()->getType(); 884 } 885 886 void dumpToStream(raw_ostream &os) const; 887 888 static bool classof(const MemRegion* R) { 889 return R->getKind() == VarRegionKind; 890 } 891 892 bool canPrintPrettyAsExpr() const; 893 894 void printPrettyAsExpr(raw_ostream &os) const; 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; 911 912 public: 913 QualType getValueType() const { 914 return QualType(ThisPointerTy, 0); 915 } 916 917 void dumpToStream(raw_ostream &os) const; 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 { 937 // FIXME: We can cache this if needed. 938 return getDecl()->getType(); 939 } 940 941 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 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; 953 954 bool canPrintPretty() const; 955 void printPretty(raw_ostream &os) const; 956 bool canPrintPrettyAsExpr() const; 957 void printPrettyAsExpr(raw_ostream &os) const; 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; 972 973 bool canPrintPrettyAsExpr() const; 974 void printPrettyAsExpr(raw_ostream &os) const; 975 976 void dumpToStream(raw_ostream &os) const; 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 { 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; 1040 1041 void Profile(llvm::FoldingSetNodeID& ID) const; 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 { 1064 return Ex->getType(); 1065 } 1066 1067 void dumpToStream(raw_ostream &os) const; 1068 1069 void Profile(llvm::FoldingSetNodeID &ID) const; 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; 1095 1096 void dumpToStream(raw_ostream &os) const; 1097 1098 void Profile(llvm::FoldingSetNodeID &ID) const; 1099 1100 static bool classof(const MemRegion *region) { 1101 return region->getKind() == CXXBaseObjectRegionKind; 1102 } 1103 1104 bool canPrintPrettyAsExpr() const; 1105 1106 void printPrettyAsExpr(raw_ostream &os) const; 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 NULL; 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(0), SystemGlobals(0), ImmutableGlobals(0), 1145 heap(0), unknown(0), code(0) {} 1146 1147 ~MemRegionManager(); 1148 1149 ASTContext &getContext() { return C; } 1150 1151 llvm::BumpPtrAllocator &getAllocator() { return A; } 1152 1153 /// getStackLocalsRegion - Retrieve the memory region associated with the 1154 /// specified stack frame. 1155 const StackLocalsSpaceRegion * 1156 getStackLocalsRegion(const StackFrameContext *STC); 1157 1158 /// getStackArgumentsRegion - Retrieve the memory region associated with 1159 /// function/method arguments of the specified stack frame. 1160 const StackArgumentsSpaceRegion * 1161 getStackArgumentsRegion(const StackFrameContext *STC); 1162 1163 /// getGlobalsRegion - Retrieve the memory region associated with 1164 /// global variables. 1165 const GlobalsSpaceRegion *getGlobalsRegion( 1166 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 1167 const CodeTextRegion *R = 0); 1168 1169 /// getHeapRegion - Retrieve the memory region associated with the 1170 /// generic "heap". 1171 const HeapSpaceRegion *getHeapRegion(); 1172 1173 /// getUnknownRegion - Retrieve the memory region associated with unknown 1174 /// memory space. 1175 const MemSpaceRegion *getUnknownRegion(); 1176 1177 const MemSpaceRegion *getCodeRegion(); 1178 1179 /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 1180 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 1181 const LocationContext *LC); 1182 1183 /// getCompoundLiteralRegion - Retrieve the region associated with a 1184 /// given CompoundLiteral. 1185 const CompoundLiteralRegion* 1186 getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1187 const LocationContext *LC); 1188 1189 /// getCXXThisRegion - Retrieve the [artificial] region associated with the 1190 /// parameter 'this'. 1191 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 1192 const LocationContext *LC); 1193 1194 /// \brief Retrieve or create a "symbolic" memory region. 1195 const SymbolicRegion* getSymbolicRegion(SymbolRef Sym); 1196 1197 /// \brief Return a unique symbolic region belonging to heap memory space. 1198 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym); 1199 1200 const StringRegion *getStringRegion(const StringLiteral* Str); 1201 1202 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 1203 1204 /// getVarRegion - Retrieve or create the memory region associated with 1205 /// a specified VarDecl and LocationContext. 1206 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 1207 1208 /// getVarRegion - Retrieve or create the memory region associated with 1209 /// a specified VarDecl and super region. 1210 const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR); 1211 1212 /// getElementRegion - Retrieve the memory region associated with the 1213 /// associated element type, index, and super region. 1214 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 1215 const MemRegion *superRegion, 1216 ASTContext &Ctx); 1217 1218 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 1219 const MemRegion *superRegion) { 1220 return getElementRegion(ER->getElementType(), ER->getIndex(), 1221 superRegion, ER->getContext()); 1222 } 1223 1224 /// getFieldRegion - Retrieve or create the memory region associated with 1225 /// a specified FieldDecl. 'superRegion' corresponds to the containing 1226 /// memory region (which typically represents the memory representing 1227 /// a structure or class). 1228 const FieldRegion *getFieldRegion(const FieldDecl *fd, 1229 const MemRegion* superRegion); 1230 1231 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 1232 const MemRegion *superRegion) { 1233 return getFieldRegion(FR->getDecl(), superRegion); 1234 } 1235 1236 /// getObjCIvarRegion - Retrieve or create the memory region associated with 1237 /// a specified Objective-c instance variable. 'superRegion' corresponds 1238 /// to the containing region (which typically represents the Objective-C 1239 /// object). 1240 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 1241 const MemRegion* superRegion); 1242 1243 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 1244 LocationContext const *LC); 1245 1246 /// Create a CXXBaseObjectRegion with the given base class for region 1247 /// \p Super. 1248 /// 1249 /// The type of \p Super is assumed be a class deriving from \p BaseClass. 1250 const CXXBaseObjectRegion * 1251 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super, 1252 bool IsVirtual); 1253 1254 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 1255 /// super region. 1256 const CXXBaseObjectRegion * 1257 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 1258 const MemRegion *superRegion) { 1259 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion, 1260 baseReg->isVirtual()); 1261 } 1262 1263 const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD); 1264 const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, 1265 CanQualType locTy, 1266 AnalysisDeclContext *AC); 1267 1268 /// getBlockDataRegion - Get the memory region associated with an instance 1269 /// of a block. Unlike many other MemRegions, the LocationContext* 1270 /// argument is allowed to be NULL for cases where we have no known 1271 /// context. 1272 const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, 1273 const LocationContext *lc = NULL); 1274 1275 /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended 1276 /// by static references. This differs from getCXXTempObjectRegion in the 1277 /// super-region used. 1278 const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex); 1279 1280 private: 1281 template <typename RegionTy, typename A1> 1282 RegionTy* getRegion(const A1 a1); 1283 1284 template <typename RegionTy, typename A1> 1285 RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); 1286 1287 template <typename RegionTy, typename A1, typename A2> 1288 RegionTy* getRegion(const A1 a1, const A2 a2); 1289 1290 template <typename RegionTy, typename A1, typename A2> 1291 RegionTy* getSubRegion(const A1 a1, const A2 a2, 1292 const MemRegion* superRegion); 1293 1294 template <typename RegionTy, typename A1, typename A2, typename A3> 1295 RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3, 1296 const MemRegion* superRegion); 1297 1298 template <typename REG> 1299 const REG* LazyAllocate(REG*& region); 1300 1301 template <typename REG, typename ARG> 1302 const REG* LazyAllocate(REG*& region, ARG a); 1303 }; 1304 1305 //===----------------------------------------------------------------------===// 1306 // Out-of-line member definitions. 1307 //===----------------------------------------------------------------------===// 1308 1309 inline ASTContext &MemRegion::getContext() const { 1310 return getMemRegionManager()->getContext(); 1311 } 1312 1313 } // end GR namespace 1314 1315 } // end clang namespace 1316 1317 //===----------------------------------------------------------------------===// 1318 // Pretty-printing regions. 1319 //===----------------------------------------------------------------------===// 1320 1321 namespace llvm { 1322 static inline raw_ostream &operator<<(raw_ostream &os, 1323 const clang::ento::MemRegion* R) { 1324 R->dumpToStream(os); 1325 return os; 1326 } 1327 } // end llvm namespace 1328 1329 #endif 1330