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