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