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