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