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