clang API Documentation
00001 //== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines MemRegion and its subclasses. MemRegion defines a 00011 // partially-typed abstraction of memory useful for path-sensitive dataflow 00012 // analyses. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_CLANG_GR_MEMREGION_H 00017 #define LLVM_CLANG_GR_MEMREGION_H 00018 00019 #include "clang/AST/CharUnits.h" 00020 #include "clang/AST/Decl.h" 00021 #include "clang/AST/ExprObjC.h" 00022 #include "clang/Basic/LLVM.h" 00023 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 00024 #include "llvm/Support/ErrorHandling.h" 00025 #include "llvm/ADT/FoldingSet.h" 00026 #include <string> 00027 00028 namespace llvm { 00029 class BumpPtrAllocator; 00030 } 00031 00032 namespace clang { 00033 00034 class LocationContext; 00035 class StackFrameContext; 00036 00037 namespace ento { 00038 00039 class MemRegionManager; 00040 class MemSpaceRegion; 00041 class SValBuilder; 00042 class VarRegion; 00043 class CodeTextRegion; 00044 00045 /// Represent a region's offset within the top level base region. 00046 class RegionOffset { 00047 /// The base region. 00048 const MemRegion *R; 00049 00050 /// The bit offset within the base region. It shouldn't be negative. 00051 int64_t Offset; 00052 00053 public: 00054 RegionOffset(const MemRegion *r) : R(r), Offset(0) {} 00055 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} 00056 00057 const MemRegion *getRegion() const { return R; } 00058 int64_t getOffset() const { return Offset; } 00059 }; 00060 00061 //===----------------------------------------------------------------------===// 00062 // Base region classes. 00063 //===----------------------------------------------------------------------===// 00064 00065 /// MemRegion - The root abstract class for all memory regions. 00066 class MemRegion : public llvm::FoldingSetNode { 00067 friend class MemRegionManager; 00068 public: 00069 enum Kind { 00070 // Memory spaces. 00071 GenericMemSpaceRegionKind, 00072 StackLocalsSpaceRegionKind, 00073 StackArgumentsSpaceRegionKind, 00074 HeapSpaceRegionKind, 00075 UnknownSpaceRegionKind, 00076 StaticGlobalSpaceRegionKind, 00077 GlobalInternalSpaceRegionKind, 00078 GlobalSystemSpaceRegionKind, 00079 GlobalImmutableSpaceRegionKind, 00080 BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind, 00081 END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 00082 BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind, 00083 END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 00084 BEG_MEMSPACES = GenericMemSpaceRegionKind, 00085 END_MEMSPACES = GlobalImmutableSpaceRegionKind, 00086 // Untyped regions. 00087 SymbolicRegionKind, 00088 AllocaRegionKind, 00089 BlockDataRegionKind, 00090 // Typed regions. 00091 BEG_TYPED_REGIONS, 00092 FunctionTextRegionKind = BEG_TYPED_REGIONS, 00093 BlockTextRegionKind, 00094 BEG_TYPED_VALUE_REGIONS, 00095 CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS, 00096 CXXThisRegionKind, 00097 StringRegionKind, 00098 ObjCStringRegionKind, 00099 ElementRegionKind, 00100 // Decl Regions. 00101 BEG_DECL_REGIONS, 00102 VarRegionKind = BEG_DECL_REGIONS, 00103 FieldRegionKind, 00104 ObjCIvarRegionKind, 00105 END_DECL_REGIONS = ObjCIvarRegionKind, 00106 CXXTempObjectRegionKind, 00107 CXXBaseObjectRegionKind, 00108 END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind, 00109 END_TYPED_REGIONS = CXXBaseObjectRegionKind 00110 }; 00111 00112 private: 00113 const Kind kind; 00114 00115 protected: 00116 MemRegion(Kind k) : kind(k) {} 00117 virtual ~MemRegion(); 00118 00119 public: 00120 ASTContext &getContext() const; 00121 00122 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 00123 00124 virtual MemRegionManager* getMemRegionManager() const = 0; 00125 00126 const MemSpaceRegion *getMemorySpace() const; 00127 00128 const MemRegion *getBaseRegion() const; 00129 00130 const MemRegion *StripCasts() const; 00131 00132 bool hasGlobalsOrParametersStorage() const; 00133 00134 bool hasStackStorage() const; 00135 00136 bool hasStackNonParametersStorage() const; 00137 00138 bool hasStackParametersStorage() const; 00139 00140 /// Compute the offset within the top level memory object. 00141 RegionOffset getAsOffset() const; 00142 00143 /// \brief Get a string representation of a region for debug use. 00144 std::string getString() const; 00145 00146 virtual void dumpToStream(raw_ostream &os) const; 00147 00148 void dump() const; 00149 00150 /// \brief Print the region for use in diagnostics. 00151 virtual void dumpPretty(raw_ostream &os) const; 00152 00153 Kind getKind() const { return kind; } 00154 00155 template<typename RegionTy> const RegionTy* getAs() const; 00156 00157 virtual bool isBoundable() const { return false; } 00158 00159 static bool classof(const MemRegion*) { return true; } 00160 }; 00161 00162 /// MemSpaceRegion - A memory region that represents a "memory space"; 00163 /// for example, the set of global variables, the stack frame, etc. 00164 class MemSpaceRegion : public MemRegion { 00165 protected: 00166 friend class MemRegionManager; 00167 00168 MemRegionManager *Mgr; 00169 00170 MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind) 00171 : MemRegion(k), Mgr(mgr) { 00172 assert(classof(this)); 00173 } 00174 00175 MemRegionManager* getMemRegionManager() const { return Mgr; } 00176 00177 public: 00178 bool isBoundable() const { return false; } 00179 00180 void Profile(llvm::FoldingSetNodeID &ID) const; 00181 00182 static bool classof(const MemRegion *R) { 00183 Kind k = R->getKind(); 00184 return k >= BEG_MEMSPACES && k <= END_MEMSPACES; 00185 } 00186 }; 00187 00188 class GlobalsSpaceRegion : public MemSpaceRegion { 00189 virtual void anchor(); 00190 protected: 00191 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) 00192 : MemSpaceRegion(mgr, k) {} 00193 public: 00194 static bool classof(const MemRegion *R) { 00195 Kind k = R->getKind(); 00196 return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; 00197 } 00198 }; 00199 00200 /// \brief The region of the static variables within the current CodeTextRegion 00201 /// scope. 00202 /// 00203 /// Currently, only the static locals are placed there, so we know that these 00204 /// variables do not get invalidated by calls to other functions. 00205 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { 00206 friend class MemRegionManager; 00207 00208 const CodeTextRegion *CR; 00209 00210 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) 00211 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {} 00212 00213 public: 00214 void Profile(llvm::FoldingSetNodeID &ID) const; 00215 00216 void dumpToStream(raw_ostream &os) const; 00217 00218 const CodeTextRegion *getCodeRegion() const { return CR; } 00219 00220 static bool classof(const MemRegion *R) { 00221 return R->getKind() == StaticGlobalSpaceRegionKind; 00222 } 00223 }; 00224 00225 /// \brief The region for all the non-static global variables. 00226 /// 00227 /// This class is further split into subclasses for efficient implementation of 00228 /// invalidating a set of related global values as is done in 00229 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent 00230 /// globals, we invalidate the whole parent region). 00231 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { 00232 friend class MemRegionManager; 00233 00234 protected: 00235 NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) 00236 : GlobalsSpaceRegion(mgr, k) {} 00237 00238 public: 00239 00240 void dumpToStream(raw_ostream &os) const; 00241 00242 static bool classof(const MemRegion *R) { 00243 Kind k = R->getKind(); 00244 return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES && 00245 k <= END_NON_STATIC_GLOBAL_MEMSPACES; 00246 } 00247 }; 00248 00249 /// \brief The region containing globals which are defined in system/external 00250 /// headers and are considered modifiable by system calls (ex: errno). 00251 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { 00252 friend class MemRegionManager; 00253 00254 GlobalSystemSpaceRegion(MemRegionManager *mgr) 00255 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} 00256 00257 public: 00258 00259 void dumpToStream(raw_ostream &os) const; 00260 00261 static bool classof(const MemRegion *R) { 00262 return R->getKind() == GlobalSystemSpaceRegionKind; 00263 } 00264 }; 00265 00266 /// \brief The region containing globals which are considered not to be modified 00267 /// or point to data which could be modified as a result of a function call 00268 /// (system or internal). Ex: Const global scalars would be modeled as part of 00269 /// this region. This region also includes most system globals since they have 00270 /// low chance of being modified. 00271 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { 00272 friend class MemRegionManager; 00273 00274 GlobalImmutableSpaceRegion(MemRegionManager *mgr) 00275 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} 00276 00277 public: 00278 00279 void dumpToStream(raw_ostream &os) const; 00280 00281 static bool classof(const MemRegion *R) { 00282 return R->getKind() == GlobalImmutableSpaceRegionKind; 00283 } 00284 }; 00285 00286 /// \brief The region containing globals which can be modified by calls to 00287 /// "internally" defined functions - (for now just) functions other then system 00288 /// calls. 00289 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { 00290 friend class MemRegionManager; 00291 00292 GlobalInternalSpaceRegion(MemRegionManager *mgr) 00293 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} 00294 00295 public: 00296 00297 void dumpToStream(raw_ostream &os) const; 00298 00299 static bool classof(const MemRegion *R) { 00300 return R->getKind() == GlobalInternalSpaceRegionKind; 00301 } 00302 }; 00303 00304 class HeapSpaceRegion : public MemSpaceRegion { 00305 virtual void anchor(); 00306 friend class MemRegionManager; 00307 00308 HeapSpaceRegion(MemRegionManager *mgr) 00309 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} 00310 public: 00311 static bool classof(const MemRegion *R) { 00312 return R->getKind() == HeapSpaceRegionKind; 00313 } 00314 }; 00315 00316 class UnknownSpaceRegion : public MemSpaceRegion { 00317 virtual void anchor(); 00318 friend class MemRegionManager; 00319 UnknownSpaceRegion(MemRegionManager *mgr) 00320 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} 00321 public: 00322 static bool classof(const MemRegion *R) { 00323 return R->getKind() == UnknownSpaceRegionKind; 00324 } 00325 }; 00326 00327 class StackSpaceRegion : public MemSpaceRegion { 00328 private: 00329 const StackFrameContext *SFC; 00330 00331 protected: 00332 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) 00333 : MemSpaceRegion(mgr, k), SFC(sfc) { 00334 assert(classof(this)); 00335 } 00336 00337 public: 00338 const StackFrameContext *getStackFrame() const { return SFC; } 00339 00340 void Profile(llvm::FoldingSetNodeID &ID) const; 00341 00342 static bool classof(const MemRegion *R) { 00343 Kind k = R->getKind(); 00344 return k >= StackLocalsSpaceRegionKind && 00345 k <= StackArgumentsSpaceRegionKind; 00346 } 00347 }; 00348 00349 class StackLocalsSpaceRegion : public StackSpaceRegion { 00350 virtual void anchor(); 00351 friend class MemRegionManager; 00352 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 00353 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} 00354 public: 00355 static bool classof(const MemRegion *R) { 00356 return R->getKind() == StackLocalsSpaceRegionKind; 00357 } 00358 }; 00359 00360 class StackArgumentsSpaceRegion : public StackSpaceRegion { 00361 private: 00362 virtual void anchor(); 00363 friend class MemRegionManager; 00364 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 00365 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} 00366 public: 00367 static bool classof(const MemRegion *R) { 00368 return R->getKind() == StackArgumentsSpaceRegionKind; 00369 } 00370 }; 00371 00372 00373 /// SubRegion - A region that subsets another larger region. Most regions 00374 /// are subclasses of SubRegion. 00375 class SubRegion : public MemRegion { 00376 private: 00377 virtual void anchor(); 00378 protected: 00379 const MemRegion* superRegion; 00380 SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} 00381 public: 00382 const MemRegion* getSuperRegion() const { 00383 return superRegion; 00384 } 00385 00386 /// getExtent - Returns the size of the region in bytes. 00387 virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { 00388 return UnknownVal(); 00389 } 00390 00391 MemRegionManager* getMemRegionManager() const; 00392 00393 bool isSubRegionOf(const MemRegion* R) const; 00394 00395 static bool classof(const MemRegion* R) { 00396 return R->getKind() > END_MEMSPACES; 00397 } 00398 }; 00399 00400 //===----------------------------------------------------------------------===// 00401 // MemRegion subclasses. 00402 //===----------------------------------------------------------------------===// 00403 00404 /// AllocaRegion - A region that represents an untyped blob of bytes created 00405 /// by a call to 'alloca'. 00406 class AllocaRegion : public SubRegion { 00407 friend class MemRegionManager; 00408 protected: 00409 unsigned Cnt; // Block counter. Used to distinguish different pieces of 00410 // memory allocated by alloca at the same call site. 00411 const Expr *Ex; 00412 00413 AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion) 00414 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} 00415 00416 public: 00417 00418 const Expr *getExpr() const { return Ex; } 00419 00420 bool isBoundable() const { return true; } 00421 00422 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 00423 00424 void Profile(llvm::FoldingSetNodeID& ID) const; 00425 00426 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, 00427 unsigned Cnt, const MemRegion *superRegion); 00428 00429 void dumpToStream(raw_ostream &os) const; 00430 00431 static bool classof(const MemRegion* R) { 00432 return R->getKind() == AllocaRegionKind; 00433 } 00434 }; 00435 00436 /// TypedRegion - An abstract class representing regions that are typed. 00437 class TypedRegion : public SubRegion { 00438 public: 00439 virtual void anchor(); 00440 protected: 00441 TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} 00442 00443 public: 00444 virtual QualType getLocationType() const = 0; 00445 00446 QualType getDesugaredLocationType(ASTContext &Context) const { 00447 return getLocationType().getDesugaredType(Context); 00448 } 00449 00450 bool isBoundable() const { return true; } 00451 00452 static bool classof(const MemRegion* R) { 00453 unsigned k = R->getKind(); 00454 return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; 00455 } 00456 }; 00457 00458 /// TypedValueRegion - An abstract class representing regions having a typed value. 00459 class TypedValueRegion : public TypedRegion { 00460 public: 00461 virtual void anchor(); 00462 protected: 00463 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {} 00464 00465 public: 00466 virtual QualType getValueType() const = 0; 00467 00468 virtual QualType getLocationType() const { 00469 // FIXME: We can possibly optimize this later to cache this value. 00470 QualType T = getValueType(); 00471 ASTContext &ctx = getContext(); 00472 if (T->getAs<ObjCObjectType>()) 00473 return ctx.getObjCObjectPointerType(T); 00474 return ctx.getPointerType(getValueType()); 00475 } 00476 00477 QualType getDesugaredValueType(ASTContext &Context) const { 00478 QualType T = getValueType(); 00479 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; 00480 } 00481 00482 static bool classof(const MemRegion* R) { 00483 unsigned k = R->getKind(); 00484 return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; 00485 } 00486 }; 00487 00488 00489 class CodeTextRegion : public TypedRegion { 00490 public: 00491 virtual void anchor(); 00492 protected: 00493 CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} 00494 public: 00495 bool isBoundable() const { return false; } 00496 00497 static bool classof(const MemRegion* R) { 00498 Kind k = R->getKind(); 00499 return k >= FunctionTextRegionKind && k <= BlockTextRegionKind; 00500 } 00501 }; 00502 00503 /// FunctionTextRegion - A region that represents code texts of function. 00504 class FunctionTextRegion : public CodeTextRegion { 00505 const FunctionDecl *FD; 00506 public: 00507 FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg) 00508 : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {} 00509 00510 QualType getLocationType() const { 00511 return getContext().getPointerType(FD->getType()); 00512 } 00513 00514 const FunctionDecl *getDecl() const { 00515 return FD; 00516 } 00517 00518 virtual void dumpToStream(raw_ostream &os) const; 00519 00520 void Profile(llvm::FoldingSetNodeID& ID) const; 00521 00522 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD, 00523 const MemRegion*); 00524 00525 static bool classof(const MemRegion* R) { 00526 return R->getKind() == FunctionTextRegionKind; 00527 } 00528 }; 00529 00530 00531 /// BlockTextRegion - A region that represents code texts of blocks (closures). 00532 /// Blocks are represented with two kinds of regions. BlockTextRegions 00533 /// represent the "code", while BlockDataRegions represent instances of blocks, 00534 /// which correspond to "code+data". The distinction is important, because 00535 /// like a closure a block captures the values of externally referenced 00536 /// variables. 00537 class BlockTextRegion : public CodeTextRegion { 00538 friend class MemRegionManager; 00539 00540 const BlockDecl *BD; 00541 AnalysisDeclContext *AC; 00542 CanQualType locTy; 00543 00544 BlockTextRegion(const BlockDecl *bd, CanQualType lTy, 00545 AnalysisDeclContext *ac, const MemRegion* sreg) 00546 : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {} 00547 00548 public: 00549 QualType getLocationType() const { 00550 return locTy; 00551 } 00552 00553 const BlockDecl *getDecl() const { 00554 return BD; 00555 } 00556 00557 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } 00558 00559 virtual void dumpToStream(raw_ostream &os) const; 00560 00561 void Profile(llvm::FoldingSetNodeID& ID) const; 00562 00563 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, 00564 CanQualType, const AnalysisDeclContext*, 00565 const MemRegion*); 00566 00567 static bool classof(const MemRegion* R) { 00568 return R->getKind() == BlockTextRegionKind; 00569 } 00570 }; 00571 00572 /// BlockDataRegion - A region that represents a block instance. 00573 /// Blocks are represented with two kinds of regions. BlockTextRegions 00574 /// represent the "code", while BlockDataRegions represent instances of blocks, 00575 /// which correspond to "code+data". The distinction is important, because 00576 /// like a closure a block captures the values of externally referenced 00577 /// variables. 00578 class BlockDataRegion : public SubRegion { 00579 friend class MemRegionManager; 00580 const BlockTextRegion *BC; 00581 const LocationContext *LC; // Can be null */ 00582 void *ReferencedVars; 00583 void *OriginalVars; 00584 00585 BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, 00586 const MemRegion *sreg) 00587 : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), 00588 ReferencedVars(0), OriginalVars(0) {} 00589 00590 public: 00591 const BlockTextRegion *getCodeRegion() const { return BC; } 00592 00593 const BlockDecl *getDecl() const { return BC->getDecl(); } 00594 00595 class referenced_vars_iterator { 00596 const MemRegion * const *R; 00597 const MemRegion * const *OriginalR; 00598 public: 00599 explicit referenced_vars_iterator(const MemRegion * const *r, 00600 const MemRegion * const *originalR) 00601 : R(r), OriginalR(originalR) {} 00602 00603 operator const MemRegion * const *() const { 00604 return R; 00605 } 00606 00607 const MemRegion *getCapturedRegion() const { 00608 return *R; 00609 } 00610 const MemRegion *getOriginalRegion() const { 00611 return *OriginalR; 00612 } 00613 00614 const VarRegion* operator*() const { 00615 return cast<VarRegion>(*R); 00616 } 00617 00618 bool operator==(const referenced_vars_iterator &I) const { 00619 return I.R == R; 00620 } 00621 bool operator!=(const referenced_vars_iterator &I) const { 00622 return I.R != R; 00623 } 00624 referenced_vars_iterator &operator++() { 00625 ++R; 00626 ++OriginalR; 00627 return *this; 00628 } 00629 }; 00630 00631 referenced_vars_iterator referenced_vars_begin() const; 00632 referenced_vars_iterator referenced_vars_end() const; 00633 00634 virtual void dumpToStream(raw_ostream &os) const; 00635 00636 void Profile(llvm::FoldingSetNodeID& ID) const; 00637 00638 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, 00639 const LocationContext *, const MemRegion *); 00640 00641 static bool classof(const MemRegion* R) { 00642 return R->getKind() == BlockDataRegionKind; 00643 } 00644 private: 00645 void LazyInitializeReferencedVars(); 00646 }; 00647 00648 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region 00649 /// clases, SymbolicRegion represents a region that serves as an alias for 00650 /// either a real region, a NULL pointer, etc. It essentially is used to 00651 /// map the concept of symbolic values into the domain of regions. Symbolic 00652 /// regions do not need to be typed. 00653 class SymbolicRegion : public SubRegion { 00654 protected: 00655 const SymbolRef sym; 00656 00657 public: 00658 SymbolicRegion(const SymbolRef s, const MemRegion* sreg) 00659 : SubRegion(sreg, SymbolicRegionKind), sym(s) {} 00660 00661 SymbolRef getSymbol() const { 00662 return sym; 00663 } 00664 00665 bool isBoundable() const { return true; } 00666 00667 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 00668 00669 void Profile(llvm::FoldingSetNodeID& ID) const; 00670 00671 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 00672 SymbolRef sym, 00673 const MemRegion* superRegion); 00674 00675 void dumpToStream(raw_ostream &os) const; 00676 00677 static bool classof(const MemRegion* R) { 00678 return R->getKind() == SymbolicRegionKind; 00679 } 00680 }; 00681 00682 /// StringRegion - Region associated with a StringLiteral. 00683 class StringRegion : public TypedValueRegion { 00684 friend class MemRegionManager; 00685 const StringLiteral* Str; 00686 protected: 00687 00688 StringRegion(const StringLiteral* str, const MemRegion* sreg) 00689 : TypedValueRegion(sreg, StringRegionKind), Str(str) {} 00690 00691 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 00692 const StringLiteral* Str, 00693 const MemRegion* superRegion); 00694 00695 public: 00696 00697 const StringLiteral* getStringLiteral() const { return Str; } 00698 00699 QualType getValueType() const { 00700 return Str->getType(); 00701 } 00702 00703 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 00704 00705 bool isBoundable() const { return false; } 00706 00707 void Profile(llvm::FoldingSetNodeID& ID) const { 00708 ProfileRegion(ID, Str, superRegion); 00709 } 00710 00711 void dumpToStream(raw_ostream &os) const; 00712 00713 static bool classof(const MemRegion* R) { 00714 return R->getKind() == StringRegionKind; 00715 } 00716 }; 00717 00718 /// The region associated with an ObjCStringLiteral. 00719 class ObjCStringRegion : public TypedValueRegion { 00720 friend class MemRegionManager; 00721 const ObjCStringLiteral* Str; 00722 protected: 00723 00724 ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg) 00725 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {} 00726 00727 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 00728 const ObjCStringLiteral* Str, 00729 const MemRegion* superRegion); 00730 00731 public: 00732 00733 const ObjCStringLiteral* getObjCStringLiteral() const { return Str; } 00734 00735 QualType getValueType() const { 00736 return Str->getType(); 00737 } 00738 00739 bool isBoundable() const { return false; } 00740 00741 void Profile(llvm::FoldingSetNodeID& ID) const { 00742 ProfileRegion(ID, Str, superRegion); 00743 } 00744 00745 void dumpToStream(raw_ostream &os) const; 00746 00747 static bool classof(const MemRegion* R) { 00748 return R->getKind() == ObjCStringRegionKind; 00749 } 00750 }; 00751 00752 /// CompoundLiteralRegion - A memory region representing a compound literal. 00753 /// Compound literals are essentially temporaries that are stack allocated 00754 /// or in the global constant pool. 00755 class CompoundLiteralRegion : public TypedValueRegion { 00756 private: 00757 friend class MemRegionManager; 00758 const CompoundLiteralExpr *CL; 00759 00760 CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg) 00761 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} 00762 00763 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 00764 const CompoundLiteralExpr *CL, 00765 const MemRegion* superRegion); 00766 public: 00767 QualType getValueType() const { 00768 return CL->getType(); 00769 } 00770 00771 bool isBoundable() const { return !CL->isFileScope(); } 00772 00773 void Profile(llvm::FoldingSetNodeID& ID) const; 00774 00775 void dumpToStream(raw_ostream &os) const; 00776 00777 const CompoundLiteralExpr *getLiteralExpr() const { return CL; } 00778 00779 static bool classof(const MemRegion* R) { 00780 return R->getKind() == CompoundLiteralRegionKind; 00781 } 00782 }; 00783 00784 class DeclRegion : public TypedValueRegion { 00785 protected: 00786 const Decl *D; 00787 00788 DeclRegion(const Decl *d, const MemRegion* sReg, Kind k) 00789 : TypedValueRegion(sReg, k), D(d) {} 00790 00791 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 00792 const MemRegion* superRegion, Kind k); 00793 00794 public: 00795 const Decl *getDecl() const { return D; } 00796 void Profile(llvm::FoldingSetNodeID& ID) const; 00797 00798 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 00799 00800 static bool classof(const MemRegion* R) { 00801 unsigned k = R->getKind(); 00802 return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS; 00803 } 00804 }; 00805 00806 class VarRegion : public DeclRegion { 00807 friend class MemRegionManager; 00808 00809 // Constructors and private methods. 00810 VarRegion(const VarDecl *vd, const MemRegion* sReg) 00811 : DeclRegion(vd, sReg, VarRegionKind) {} 00812 00813 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, 00814 const MemRegion *superRegion) { 00815 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 00816 } 00817 00818 void Profile(llvm::FoldingSetNodeID& ID) const; 00819 00820 public: 00821 const VarDecl *getDecl() const { return cast<VarDecl>(D); } 00822 00823 const StackFrameContext *getStackFrame() const; 00824 00825 QualType getValueType() const { 00826 // FIXME: We can cache this if needed. 00827 return getDecl()->getType(); 00828 } 00829 00830 void dumpToStream(raw_ostream &os) const; 00831 00832 static bool classof(const MemRegion* R) { 00833 return R->getKind() == VarRegionKind; 00834 } 00835 00836 void dumpPretty(raw_ostream &os) const; 00837 }; 00838 00839 /// CXXThisRegion - Represents the region for the implicit 'this' parameter 00840 /// in a call to a C++ method. This region doesn't represent the object 00841 /// referred to by 'this', but rather 'this' itself. 00842 class CXXThisRegion : public TypedValueRegion { 00843 friend class MemRegionManager; 00844 CXXThisRegion(const PointerType *thisPointerTy, 00845 const MemRegion *sReg) 00846 : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} 00847 00848 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 00849 const PointerType *PT, 00850 const MemRegion *sReg); 00851 00852 void Profile(llvm::FoldingSetNodeID &ID) const; 00853 00854 public: 00855 QualType getValueType() const { 00856 return QualType(ThisPointerTy, 0); 00857 } 00858 00859 void dumpToStream(raw_ostream &os) const; 00860 00861 static bool classof(const MemRegion* R) { 00862 return R->getKind() == CXXThisRegionKind; 00863 } 00864 00865 private: 00866 const PointerType *ThisPointerTy; 00867 }; 00868 00869 class FieldRegion : public DeclRegion { 00870 friend class MemRegionManager; 00871 00872 FieldRegion(const FieldDecl *fd, const MemRegion* sReg) 00873 : DeclRegion(fd, sReg, FieldRegionKind) {} 00874 00875 public: 00876 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } 00877 00878 QualType getValueType() const { 00879 // FIXME: We can cache this if needed. 00880 return getDecl()->getType(); 00881 } 00882 00883 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 00884 00885 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, 00886 const MemRegion* superRegion) { 00887 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 00888 } 00889 00890 static bool classof(const MemRegion* R) { 00891 return R->getKind() == FieldRegionKind; 00892 } 00893 00894 void dumpToStream(raw_ostream &os) const; 00895 void dumpPretty(raw_ostream &os) const; 00896 }; 00897 00898 class ObjCIvarRegion : public DeclRegion { 00899 00900 friend class MemRegionManager; 00901 00902 ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg); 00903 00904 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, 00905 const MemRegion* superRegion); 00906 00907 public: 00908 const ObjCIvarDecl *getDecl() const; 00909 QualType getValueType() const; 00910 00911 void dumpToStream(raw_ostream &os) const; 00912 00913 static bool classof(const MemRegion* R) { 00914 return R->getKind() == ObjCIvarRegionKind; 00915 } 00916 }; 00917 //===----------------------------------------------------------------------===// 00918 // Auxiliary data classes for use with MemRegions. 00919 //===----------------------------------------------------------------------===// 00920 00921 class ElementRegion; 00922 00923 class RegionRawOffset { 00924 private: 00925 friend class ElementRegion; 00926 00927 const MemRegion *Region; 00928 CharUnits Offset; 00929 00930 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) 00931 : Region(reg), Offset(offset) {} 00932 00933 public: 00934 // FIXME: Eventually support symbolic offsets. 00935 CharUnits getOffset() const { return Offset; } 00936 const MemRegion *getRegion() const { return Region; } 00937 00938 void dumpToStream(raw_ostream &os) const; 00939 void dump() const; 00940 }; 00941 00942 /// \brief ElementRegin is used to represent both array elements and casts. 00943 class ElementRegion : public TypedValueRegion { 00944 friend class MemRegionManager; 00945 00946 QualType ElementType; 00947 NonLoc Index; 00948 00949 ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) 00950 : TypedValueRegion(sReg, ElementRegionKind), 00951 ElementType(elementType), Index(Idx) { 00952 assert((!isa<nonloc::ConcreteInt>(&Idx) || 00953 cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && 00954 "The index must be signed"); 00955 } 00956 00957 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 00958 SVal Idx, const MemRegion* superRegion); 00959 00960 public: 00961 00962 NonLoc getIndex() const { return Index; } 00963 00964 QualType getValueType() const { 00965 return ElementType; 00966 } 00967 00968 QualType getElementType() const { 00969 return ElementType; 00970 } 00971 /// Compute the offset within the array. The array might also be a subobject. 00972 RegionRawOffset getAsArrayOffset() const; 00973 00974 void dumpToStream(raw_ostream &os) const; 00975 00976 void Profile(llvm::FoldingSetNodeID& ID) const; 00977 00978 static bool classof(const MemRegion* R) { 00979 return R->getKind() == ElementRegionKind; 00980 } 00981 }; 00982 00983 // C++ temporary object associated with an expression. 00984 class CXXTempObjectRegion : public TypedValueRegion { 00985 friend class MemRegionManager; 00986 00987 Expr const *Ex; 00988 00989 CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 00990 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} 00991 00992 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 00993 Expr const *E, const MemRegion *sReg); 00994 00995 public: 00996 const Expr *getExpr() const { return Ex; } 00997 00998 QualType getValueType() const { 00999 return Ex->getType(); 01000 } 01001 01002 void dumpToStream(raw_ostream &os) const; 01003 01004 void Profile(llvm::FoldingSetNodeID &ID) const; 01005 01006 static bool classof(const MemRegion* R) { 01007 return R->getKind() == CXXTempObjectRegionKind; 01008 } 01009 }; 01010 01011 // CXXBaseObjectRegion represents a base object within a C++ object. It is 01012 // identified by the base class declaration and the region of its parent object. 01013 class CXXBaseObjectRegion : public TypedValueRegion { 01014 friend class MemRegionManager; 01015 01016 const CXXRecordDecl *decl; 01017 01018 CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg) 01019 : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {} 01020 01021 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 01022 const CXXRecordDecl *decl, const MemRegion *sReg); 01023 01024 public: 01025 const CXXRecordDecl *getDecl() const { return decl; } 01026 01027 QualType getValueType() const; 01028 01029 void dumpToStream(raw_ostream &os) const; 01030 01031 void Profile(llvm::FoldingSetNodeID &ID) const; 01032 01033 static bool classof(const MemRegion *region) { 01034 return region->getKind() == CXXBaseObjectRegionKind; 01035 } 01036 }; 01037 01038 template<typename RegionTy> 01039 const RegionTy* MemRegion::getAs() const { 01040 if (const RegionTy* RT = dyn_cast<RegionTy>(this)) 01041 return RT; 01042 01043 return NULL; 01044 } 01045 01046 //===----------------------------------------------------------------------===// 01047 // MemRegionManager - Factory object for creating regions. 01048 //===----------------------------------------------------------------------===// 01049 01050 class MemRegionManager { 01051 ASTContext &C; 01052 llvm::BumpPtrAllocator& A; 01053 llvm::FoldingSet<MemRegion> Regions; 01054 01055 GlobalInternalSpaceRegion *InternalGlobals; 01056 GlobalSystemSpaceRegion *SystemGlobals; 01057 GlobalImmutableSpaceRegion *ImmutableGlobals; 01058 01059 01060 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 01061 StackLocalsSpaceRegions; 01062 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> 01063 StackArgumentsSpaceRegions; 01064 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> 01065 StaticsGlobalSpaceRegions; 01066 01067 HeapSpaceRegion *heap; 01068 UnknownSpaceRegion *unknown; 01069 MemSpaceRegion *code; 01070 01071 public: 01072 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a) 01073 : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0), 01074 heap(0), unknown(0), code(0) {} 01075 01076 ~MemRegionManager(); 01077 01078 ASTContext &getContext() { return C; } 01079 01080 llvm::BumpPtrAllocator &getAllocator() { return A; } 01081 01082 /// getStackLocalsRegion - Retrieve the memory region associated with the 01083 /// specified stack frame. 01084 const StackLocalsSpaceRegion * 01085 getStackLocalsRegion(const StackFrameContext *STC); 01086 01087 /// getStackArgumentsRegion - Retrieve the memory region associated with 01088 /// function/method arguments of the specified stack frame. 01089 const StackArgumentsSpaceRegion * 01090 getStackArgumentsRegion(const StackFrameContext *STC); 01091 01092 /// getGlobalsRegion - Retrieve the memory region associated with 01093 /// global variables. 01094 const GlobalsSpaceRegion *getGlobalsRegion( 01095 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 01096 const CodeTextRegion *R = 0); 01097 01098 /// getHeapRegion - Retrieve the memory region associated with the 01099 /// generic "heap". 01100 const HeapSpaceRegion *getHeapRegion(); 01101 01102 /// getUnknownRegion - Retrieve the memory region associated with unknown 01103 /// memory space. 01104 const MemSpaceRegion *getUnknownRegion(); 01105 01106 const MemSpaceRegion *getCodeRegion(); 01107 01108 /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 01109 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 01110 const LocationContext *LC); 01111 01112 /// getCompoundLiteralRegion - Retrieve the region associated with a 01113 /// given CompoundLiteral. 01114 const CompoundLiteralRegion* 01115 getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 01116 const LocationContext *LC); 01117 01118 /// getCXXThisRegion - Retrieve the [artificial] region associated with the 01119 /// parameter 'this'. 01120 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 01121 const LocationContext *LC); 01122 01123 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 01124 const SymbolicRegion* getSymbolicRegion(SymbolRef sym); 01125 01126 const StringRegion *getStringRegion(const StringLiteral* Str); 01127 01128 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 01129 01130 /// getVarRegion - Retrieve or create the memory region associated with 01131 /// a specified VarDecl and LocationContext. 01132 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 01133 01134 /// getVarRegion - Retrieve or create the memory region associated with 01135 /// a specified VarDecl and super region. 01136 const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR); 01137 01138 /// getElementRegion - Retrieve the memory region associated with the 01139 /// associated element type, index, and super region. 01140 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 01141 const MemRegion *superRegion, 01142 ASTContext &Ctx); 01143 01144 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 01145 const MemRegion *superRegion) { 01146 return getElementRegion(ER->getElementType(), ER->getIndex(), 01147 superRegion, ER->getContext()); 01148 } 01149 01150 /// getFieldRegion - Retrieve or create the memory region associated with 01151 /// a specified FieldDecl. 'superRegion' corresponds to the containing 01152 /// memory region (which typically represents the memory representing 01153 /// a structure or class). 01154 const FieldRegion *getFieldRegion(const FieldDecl *fd, 01155 const MemRegion* superRegion); 01156 01157 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 01158 const MemRegion *superRegion) { 01159 return getFieldRegion(FR->getDecl(), superRegion); 01160 } 01161 01162 /// getObjCIvarRegion - Retrieve or create the memory region associated with 01163 /// a specified Objective-c instance variable. 'superRegion' corresponds 01164 /// to the containing region (which typically represents the Objective-C 01165 /// object). 01166 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 01167 const MemRegion* superRegion); 01168 01169 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 01170 LocationContext const *LC); 01171 01172 const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl, 01173 const MemRegion *superRegion); 01174 01175 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 01176 /// super region. 01177 const CXXBaseObjectRegion * 01178 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 01179 const MemRegion *superRegion) { 01180 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion); 01181 } 01182 01183 const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD); 01184 const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, 01185 CanQualType locTy, 01186 AnalysisDeclContext *AC); 01187 01188 /// getBlockDataRegion - Get the memory region associated with an instance 01189 /// of a block. Unlike many other MemRegions, the LocationContext* 01190 /// argument is allowed to be NULL for cases where we have no known 01191 /// context. 01192 const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, 01193 const LocationContext *lc = NULL); 01194 01195 private: 01196 template <typename RegionTy, typename A1> 01197 RegionTy* getRegion(const A1 a1); 01198 01199 template <typename RegionTy, typename A1> 01200 RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); 01201 01202 template <typename RegionTy, typename A1, typename A2> 01203 RegionTy* getRegion(const A1 a1, const A2 a2); 01204 01205 template <typename RegionTy, typename A1, typename A2> 01206 RegionTy* getSubRegion(const A1 a1, const A2 a2, 01207 const MemRegion* superRegion); 01208 01209 template <typename RegionTy, typename A1, typename A2, typename A3> 01210 RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3, 01211 const MemRegion* superRegion); 01212 01213 template <typename REG> 01214 const REG* LazyAllocate(REG*& region); 01215 01216 template <typename REG, typename ARG> 01217 const REG* LazyAllocate(REG*& region, ARG a); 01218 }; 01219 01220 //===----------------------------------------------------------------------===// 01221 // Out-of-line member definitions. 01222 //===----------------------------------------------------------------------===// 01223 01224 inline ASTContext &MemRegion::getContext() const { 01225 return getMemRegionManager()->getContext(); 01226 } 01227 01228 } // end GR namespace 01229 01230 } // end clang namespace 01231 01232 //===----------------------------------------------------------------------===// 01233 // Pretty-printing regions. 01234 //===----------------------------------------------------------------------===// 01235 01236 namespace llvm { 01237 static inline raw_ostream &operator<<(raw_ostream &os, 01238 const clang::ento::MemRegion* R) { 01239 R->dumpToStream(os); 01240 return os; 01241 } 01242 } // end llvm namespace 01243 01244 #endif