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_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
17 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
18 
19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/CharUnits.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclObjC.h"
23 #include "clang/AST/DeclarationName.h"
24 #include "clang/AST/Expr.h"
25 #include "clang/AST/ExprObjC.h"
26 #include "clang/AST/Type.h"
27 #include "clang/Analysis/AnalysisDeclContext.h"
28 #include "clang/Basic/LLVM.h"
29 #include "clang/Basic/SourceLocation.h"
30 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
31 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
32 #include "llvm/ADT/DenseMap.h"
33 #include "llvm/ADT/FoldingSet.h"
34 #include "llvm/ADT/Optional.h"
35 #include "llvm/ADT/PointerIntPair.h"
36 #include "llvm/Support/Allocator.h"
37 #include "llvm/Support/Casting.h"
38 #include <cassert>
39 #include <cstdint>
40 #include <limits>
41 #include <string>
42 #include <utility>
43 
44 namespace clang {
45 
46 class AnalysisDeclContext;
47 class CXXRecordDecl;
48 class Decl;
49 class LocationContext;
50 class StackFrameContext;
51 
52 namespace ento {
53 
54 class CodeTextRegion;
55 class MemRegion;
56 class MemRegionManager;
57 class MemSpaceRegion;
58 class SValBuilder;
59 class SymbolicRegion;
60 class VarRegion;
61 
62 /// Represent a region's offset within the top level base region.
63 class RegionOffset {
64   /// The base region.
65   const MemRegion *R = nullptr;
66 
67   /// The bit offset within the base region. Can be negative.
68   int64_t Offset;
69 
70 public:
71   // We're using a const instead of an enumeration due to the size required;
72   // Visual Studio will only create enumerations of size int, not long long.
73   static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
74 
75   RegionOffset() = default;
RegionOffset(const MemRegion * r,int64_t off)76   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
77 
getRegion()78   const MemRegion *getRegion() const { return R; }
79 
hasSymbolicOffset()80   bool hasSymbolicOffset() const { return Offset == Symbolic; }
81 
getOffset()82   int64_t getOffset() const {
83     assert(!hasSymbolicOffset());
84     return Offset;
85   }
86 
isValid()87   bool isValid() const { return R; }
88 };
89 
90 //===----------------------------------------------------------------------===//
91 // Base region classes.
92 //===----------------------------------------------------------------------===//
93 
94 /// MemRegion - The root abstract class for all memory regions.
95 class MemRegion : public llvm::FoldingSetNode {
96 public:
97   enum Kind {
98 #define REGION(Id, Parent) Id ## Kind,
99 #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
100 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
101   };
102 
103 private:
104   const Kind kind;
105   mutable Optional<RegionOffset> cachedOffset;
106 
107 protected:
MemRegion(Kind k)108   MemRegion(Kind k) : kind(k) {}
109   virtual ~MemRegion();
110 
111 public:
112   ASTContext &getContext() const;
113 
114   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
115 
116   virtual MemRegionManager* getMemRegionManager() const = 0;
117 
118   const MemSpaceRegion *getMemorySpace() const;
119 
120   const MemRegion *getBaseRegion() const;
121 
122   /// Recursively retrieve the region of the most derived class instance of
123   /// regions of C++ base class instances.
124   const MemRegion *getMostDerivedObjectRegion() const;
125 
126   /// Check if the region is a subregion of the given region.
127   /// Each region is a subregion of itself.
128   virtual bool isSubRegionOf(const MemRegion *R) const;
129 
130   const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
131 
132   /// If this is a symbolic region, returns the region. Otherwise,
133   /// goes up the base chain looking for the first symbolic base region.
134   const SymbolicRegion *getSymbolicBase() const;
135 
136   bool hasGlobalsOrParametersStorage() const;
137 
138   bool hasStackStorage() const;
139 
140   bool hasStackNonParametersStorage() const;
141 
142   bool hasStackParametersStorage() const;
143 
144   /// Compute the offset within the top level memory object.
145   RegionOffset getAsOffset() const;
146 
147   /// Get a string representation of a region for debug use.
148   std::string getString() const;
149 
150   virtual void dumpToStream(raw_ostream &os) const;
151 
152   void dump() const;
153 
154   /// Returns true if this region can be printed in a user-friendly way.
155   virtual bool canPrintPretty() const;
156 
157   /// Print the region for use in diagnostics.
158   virtual void printPretty(raw_ostream &os) const;
159 
160   /// Returns true if this region's textual representation can be used
161   /// as part of a larger expression.
162   virtual bool canPrintPrettyAsExpr() const;
163 
164   /// Print the region as expression.
165   ///
166   /// When this region represents a subexpression, the method is for printing
167   /// an expression containing it.
168   virtual void printPrettyAsExpr(raw_ostream &os) const;
169 
getKind()170   Kind getKind() const { return kind; }
171 
172   template<typename RegionTy> const RegionTy* getAs() const;
173 
isBoundable()174   virtual bool isBoundable() const { return false; }
175 
176   /// Get descriptive name for memory region. The name is obtained from
177   /// the variable/field declaration retrieved from the memory region.
178   /// Regions that point to an element of an array are returned as: "arr[0]".
179   /// Regions that point to a struct are returned as: "st.var".
180   //
181   /// \param UseQuotes Set if the name should be quoted.
182   ///
183   /// \returns variable name for memory region
184   std::string getDescriptiveName(bool UseQuotes = true) const;
185 
186   /// Retrieve source range from memory region. The range retrieval
187   /// is based on the decl obtained from the memory region.
188   /// For a VarRegion the range of the base region is returned.
189   /// For a FieldRegion the range of the field is returned.
190   /// If no declaration is found, an empty source range is returned.
191   /// The client is responsible for checking if the returned range is valid.
192   ///
193   /// \returns source range for declaration retrieved from memory region
194   SourceRange sourceRange() const;
195 };
196 
197 /// MemSpaceRegion - A memory region that represents a "memory space";
198 ///  for example, the set of global variables, the stack frame, etc.
199 class MemSpaceRegion : public MemRegion {
200 protected:
201   MemRegionManager *Mgr;
202 
MemSpaceRegion(MemRegionManager * mgr,Kind k)203   MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) {
204     assert(classof(this));
205     assert(mgr);
206   }
207 
getMemRegionManager()208   MemRegionManager* getMemRegionManager() const override { return Mgr; }
209 
210 public:
isBoundable()211   bool isBoundable() const override { return false; }
212 
213   void Profile(llvm::FoldingSetNodeID &ID) const override;
214 
classof(const MemRegion * R)215   static bool classof(const MemRegion *R) {
216     Kind k = R->getKind();
217     return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
218   }
219 };
220 
221 /// CodeSpaceRegion - The memory space that holds the executable code of
222 /// functions and blocks.
223 class CodeSpaceRegion : public MemSpaceRegion {
224   friend class MemRegionManager;
225 
CodeSpaceRegion(MemRegionManager * mgr)226   CodeSpaceRegion(MemRegionManager *mgr)
227       : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
228 
229 public:
230   void dumpToStream(raw_ostream &os) const override;
231 
classof(const MemRegion * R)232   static bool classof(const MemRegion *R) {
233     return R->getKind() == CodeSpaceRegionKind;
234   }
235 };
236 
237 class GlobalsSpaceRegion : public MemSpaceRegion {
238   virtual void anchor();
239 
240 protected:
GlobalsSpaceRegion(MemRegionManager * mgr,Kind k)241   GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) {
242     assert(classof(this));
243   }
244 
245 public:
classof(const MemRegion * R)246   static bool classof(const MemRegion *R) {
247     Kind k = R->getKind();
248     return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
249   }
250 };
251 
252 /// The region of the static variables within the current CodeTextRegion
253 /// scope.
254 ///
255 /// Currently, only the static locals are placed there, so we know that these
256 /// variables do not get invalidated by calls to other functions.
257 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
258   friend class MemRegionManager;
259 
260   const CodeTextRegion *CR;
261 
StaticGlobalSpaceRegion(MemRegionManager * mgr,const CodeTextRegion * cr)262   StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
263       : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
264     assert(cr);
265   }
266 
267 public:
268   void Profile(llvm::FoldingSetNodeID &ID) const override;
269 
270   void dumpToStream(raw_ostream &os) const override;
271 
getCodeRegion()272   const CodeTextRegion *getCodeRegion() const { return CR; }
273 
classof(const MemRegion * R)274   static bool classof(const MemRegion *R) {
275     return R->getKind() == StaticGlobalSpaceRegionKind;
276   }
277 };
278 
279 /// The region for all the non-static global variables.
280 ///
281 /// This class is further split into subclasses for efficient implementation of
282 /// invalidating a set of related global values as is done in
283 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
284 /// globals, we invalidate the whole parent region).
285 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
286   void anchor() override;
287 
288 protected:
NonStaticGlobalSpaceRegion(MemRegionManager * mgr,Kind k)289   NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
290       : GlobalsSpaceRegion(mgr, k) {
291     assert(classof(this));
292   }
293 
294 public:
classof(const MemRegion * R)295   static bool classof(const MemRegion *R) {
296     Kind k = R->getKind();
297     return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
298            k <= END_NON_STATIC_GLOBAL_MEMSPACES;
299   }
300 };
301 
302 /// The region containing globals which are defined in system/external
303 /// headers and are considered modifiable by system calls (ex: errno).
304 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
305   friend class MemRegionManager;
306 
GlobalSystemSpaceRegion(MemRegionManager * mgr)307   GlobalSystemSpaceRegion(MemRegionManager *mgr)
308       : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
309 
310 public:
311   void dumpToStream(raw_ostream &os) const override;
312 
classof(const MemRegion * R)313   static bool classof(const MemRegion *R) {
314     return R->getKind() == GlobalSystemSpaceRegionKind;
315   }
316 };
317 
318 /// The region containing globals which are considered not to be modified
319 /// or point to data which could be modified as a result of a function call
320 /// (system or internal). Ex: Const global scalars would be modeled as part of
321 /// this region. This region also includes most system globals since they have
322 /// low chance of being modified.
323 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
324   friend class MemRegionManager;
325 
GlobalImmutableSpaceRegion(MemRegionManager * mgr)326   GlobalImmutableSpaceRegion(MemRegionManager *mgr)
327       : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
328 
329 public:
330   void dumpToStream(raw_ostream &os) const override;
331 
classof(const MemRegion * R)332   static bool classof(const MemRegion *R) {
333     return R->getKind() == GlobalImmutableSpaceRegionKind;
334   }
335 };
336 
337 /// The region containing globals which can be modified by calls to
338 /// "internally" defined functions - (for now just) functions other then system
339 /// calls.
340 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
341   friend class MemRegionManager;
342 
GlobalInternalSpaceRegion(MemRegionManager * mgr)343   GlobalInternalSpaceRegion(MemRegionManager *mgr)
344       : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
345 
346 public:
347   void dumpToStream(raw_ostream &os) const override;
348 
classof(const MemRegion * R)349   static bool classof(const MemRegion *R) {
350     return R->getKind() == GlobalInternalSpaceRegionKind;
351   }
352 };
353 
354 class HeapSpaceRegion : public MemSpaceRegion {
355   friend class MemRegionManager;
356 
HeapSpaceRegion(MemRegionManager * mgr)357   HeapSpaceRegion(MemRegionManager *mgr)
358       : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
359 
360 public:
361   void dumpToStream(raw_ostream &os) const override;
362 
classof(const MemRegion * R)363   static bool classof(const MemRegion *R) {
364     return R->getKind() == HeapSpaceRegionKind;
365   }
366 };
367 
368 class UnknownSpaceRegion : public MemSpaceRegion {
369   friend class MemRegionManager;
370 
UnknownSpaceRegion(MemRegionManager * mgr)371   UnknownSpaceRegion(MemRegionManager *mgr)
372       : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
373 
374 public:
375   void dumpToStream(raw_ostream &os) const override;
376 
classof(const MemRegion * R)377   static bool classof(const MemRegion *R) {
378     return R->getKind() == UnknownSpaceRegionKind;
379   }
380 };
381 
382 class StackSpaceRegion : public MemSpaceRegion {
383   virtual void anchor();
384 
385   const StackFrameContext *SFC;
386 
387 protected:
StackSpaceRegion(MemRegionManager * mgr,Kind k,const StackFrameContext * sfc)388   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
389       : MemSpaceRegion(mgr, k), SFC(sfc) {
390     assert(classof(this));
391     assert(sfc);
392   }
393 
394 public:
getStackFrame()395   const StackFrameContext *getStackFrame() const { return SFC; }
396 
397   void Profile(llvm::FoldingSetNodeID &ID) const override;
398 
classof(const MemRegion * R)399   static bool classof(const MemRegion *R) {
400     Kind k = R->getKind();
401     return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
402   }
403 };
404 
405 class StackLocalsSpaceRegion : public StackSpaceRegion {
406   friend class MemRegionManager;
407 
StackLocalsSpaceRegion(MemRegionManager * mgr,const StackFrameContext * sfc)408   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
409       : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
410 
411 public:
412   void dumpToStream(raw_ostream &os) const override;
413 
classof(const MemRegion * R)414   static bool classof(const MemRegion *R) {
415     return R->getKind() == StackLocalsSpaceRegionKind;
416   }
417 };
418 
419 class StackArgumentsSpaceRegion : public StackSpaceRegion {
420 private:
421   friend class MemRegionManager;
422 
StackArgumentsSpaceRegion(MemRegionManager * mgr,const StackFrameContext * sfc)423   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
424       : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
425 
426 public:
427   void dumpToStream(raw_ostream &os) const override;
428 
classof(const MemRegion * R)429   static bool classof(const MemRegion *R) {
430     return R->getKind() == StackArgumentsSpaceRegionKind;
431   }
432 };
433 
434 /// SubRegion - A region that subsets another larger region.  Most regions
435 ///  are subclasses of SubRegion.
436 class SubRegion : public MemRegion {
437   virtual void anchor();
438 
439 protected:
440   const MemRegion* superRegion;
441 
SubRegion(const MemRegion * sReg,Kind k)442   SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
443     assert(classof(this));
444     assert(sReg);
445   }
446 
447 public:
getSuperRegion()448   const MemRegion* getSuperRegion() const {
449     return superRegion;
450   }
451 
452   /// getExtent - Returns the size of the region in bytes.
getExtent(SValBuilder & svalBuilder)453   virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
454     return UnknownVal();
455   }
456 
457   MemRegionManager* getMemRegionManager() const override;
458 
459   bool isSubRegionOf(const MemRegion* R) const override;
460 
classof(const MemRegion * R)461   static bool classof(const MemRegion* R) {
462     return R->getKind() > END_MEMSPACES;
463   }
464 };
465 
466 //===----------------------------------------------------------------------===//
467 // MemRegion subclasses.
468 //===----------------------------------------------------------------------===//
469 
470 /// AllocaRegion - A region that represents an untyped blob of bytes created
471 ///  by a call to 'alloca'.
472 class AllocaRegion : public SubRegion {
473   friend class MemRegionManager;
474 
475   // Block counter. Used to distinguish different pieces of memory allocated by
476   // alloca at the same call site.
477   unsigned Cnt;
478 
479   const Expr *Ex;
480 
AllocaRegion(const Expr * ex,unsigned cnt,const MemSpaceRegion * superRegion)481   AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
482       : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
483     assert(Ex);
484   }
485 
486   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
487                             unsigned Cnt, const MemRegion *superRegion);
488 
489 public:
getExpr()490   const Expr *getExpr() const { return Ex; }
491 
isBoundable()492   bool isBoundable() const override { return true; }
493 
494   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
495 
496   void Profile(llvm::FoldingSetNodeID& ID) const override;
497 
498   void dumpToStream(raw_ostream &os) const override;
499 
classof(const MemRegion * R)500   static bool classof(const MemRegion* R) {
501     return R->getKind() == AllocaRegionKind;
502   }
503 };
504 
505 /// TypedRegion - An abstract class representing regions that are typed.
506 class TypedRegion : public SubRegion {
507   void anchor() override;
508 
509 protected:
TypedRegion(const MemRegion * sReg,Kind k)510   TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
511     assert(classof(this));
512   }
513 
514 public:
515   virtual QualType getLocationType() const = 0;
516 
getDesugaredLocationType(ASTContext & Context)517   QualType getDesugaredLocationType(ASTContext &Context) const {
518     return getLocationType().getDesugaredType(Context);
519   }
520 
isBoundable()521   bool isBoundable() const override { return true; }
522 
classof(const MemRegion * R)523   static bool classof(const MemRegion* R) {
524     unsigned k = R->getKind();
525     return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
526   }
527 };
528 
529 /// TypedValueRegion - An abstract class representing regions having a typed value.
530 class TypedValueRegion : public TypedRegion {
531   void anchor() override;
532 
533 protected:
TypedValueRegion(const MemRegion * sReg,Kind k)534   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
535     assert(classof(this));
536   }
537 
538 public:
539   virtual QualType getValueType() const = 0;
540 
getLocationType()541   QualType getLocationType() const override {
542     // FIXME: We can possibly optimize this later to cache this value.
543     QualType T = getValueType();
544     ASTContext &ctx = getContext();
545     if (T->getAs<ObjCObjectType>())
546       return ctx.getObjCObjectPointerType(T);
547     return ctx.getPointerType(getValueType());
548   }
549 
getDesugaredValueType(ASTContext & Context)550   QualType getDesugaredValueType(ASTContext &Context) const {
551     QualType T = getValueType();
552     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
553   }
554 
555   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
556 
classof(const MemRegion * R)557   static bool classof(const MemRegion* R) {
558     unsigned k = R->getKind();
559     return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
560   }
561 };
562 
563 class CodeTextRegion : public TypedRegion {
564   void anchor() override;
565 
566 protected:
CodeTextRegion(const MemSpaceRegion * sreg,Kind k)567   CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
568     assert(classof(this));
569   }
570 
571 public:
isBoundable()572   bool isBoundable() const override { return false; }
573 
classof(const MemRegion * R)574   static bool classof(const MemRegion* R) {
575     Kind k = R->getKind();
576     return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS;
577   }
578 };
579 
580 /// FunctionCodeRegion - A region that represents code texts of function.
581 class FunctionCodeRegion : public CodeTextRegion {
582   friend class MemRegionManager;
583 
584   const NamedDecl *FD;
585 
FunctionCodeRegion(const NamedDecl * fd,const CodeSpaceRegion * sreg)586   FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
587       : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
588     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
589   }
590 
591   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
592                             const MemRegion*);
593 
594 public:
getLocationType()595   QualType getLocationType() const override {
596     const ASTContext &Ctx = getContext();
597     if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
598       return Ctx.getPointerType(D->getType());
599     }
600 
601     assert(isa<ObjCMethodDecl>(FD));
602     assert(false && "Getting the type of ObjCMethod is not supported yet");
603 
604     // TODO: We might want to return a different type here (ex: id (*ty)(...))
605     //       depending on how it is used.
606     return {};
607   }
608 
getDecl()609   const NamedDecl *getDecl() const {
610     return FD;
611   }
612 
613   void dumpToStream(raw_ostream &os) const override;
614 
615   void Profile(llvm::FoldingSetNodeID& ID) const override;
616 
classof(const MemRegion * R)617   static bool classof(const MemRegion* R) {
618     return R->getKind() == FunctionCodeRegionKind;
619   }
620 };
621 
622 /// BlockCodeRegion - A region that represents code texts of blocks (closures).
623 ///  Blocks are represented with two kinds of regions.  BlockCodeRegions
624 ///  represent the "code", while BlockDataRegions represent instances of blocks,
625 ///  which correspond to "code+data".  The distinction is important, because
626 ///  like a closure a block captures the values of externally referenced
627 ///  variables.
628 class BlockCodeRegion : public CodeTextRegion {
629   friend class MemRegionManager;
630 
631   const BlockDecl *BD;
632   AnalysisDeclContext *AC;
633   CanQualType locTy;
634 
BlockCodeRegion(const BlockDecl * bd,CanQualType lTy,AnalysisDeclContext * ac,const CodeSpaceRegion * sreg)635   BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
636                   AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
637       : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
638     assert(bd);
639     assert(ac);
640     assert(lTy->getTypePtr()->isBlockPointerType());
641   }
642 
643   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
644                             CanQualType, const AnalysisDeclContext*,
645                             const MemRegion*);
646 
647 public:
getLocationType()648   QualType getLocationType() const override {
649     return locTy;
650   }
651 
getDecl()652   const BlockDecl *getDecl() const {
653     return BD;
654   }
655 
getAnalysisDeclContext()656   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
657 
658   void dumpToStream(raw_ostream &os) const override;
659 
660   void Profile(llvm::FoldingSetNodeID& ID) const override;
661 
classof(const MemRegion * R)662   static bool classof(const MemRegion* R) {
663     return R->getKind() == BlockCodeRegionKind;
664   }
665 };
666 
667 /// BlockDataRegion - A region that represents a block instance.
668 ///  Blocks are represented with two kinds of regions.  BlockCodeRegions
669 ///  represent the "code", while BlockDataRegions represent instances of blocks,
670 ///  which correspond to "code+data".  The distinction is important, because
671 ///  like a closure a block captures the values of externally referenced
672 ///  variables.
673 class BlockDataRegion : public TypedRegion {
674   friend class MemRegionManager;
675 
676   const BlockCodeRegion *BC;
677   const LocationContext *LC; // Can be null
678   unsigned BlockCount;
679   void *ReferencedVars = nullptr;
680   void *OriginalVars = nullptr;
681 
BlockDataRegion(const BlockCodeRegion * bc,const LocationContext * lc,unsigned count,const MemSpaceRegion * sreg)682   BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
683                   unsigned count, const MemSpaceRegion *sreg)
684       : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
685         BlockCount(count) {
686     assert(bc);
687     assert(lc);
688     assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
689            isa<StackLocalsSpaceRegion>(sreg) ||
690            isa<UnknownSpaceRegion>(sreg));
691   }
692 
693   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
694                             const LocationContext *, unsigned,
695                             const MemRegion *);
696 
697 public:
getCodeRegion()698   const BlockCodeRegion *getCodeRegion() const { return BC; }
699 
getDecl()700   const BlockDecl *getDecl() const { return BC->getDecl(); }
701 
getLocationType()702   QualType getLocationType() const override { return BC->getLocationType(); }
703 
704   class referenced_vars_iterator {
705     const MemRegion * const *R;
706     const MemRegion * const *OriginalR;
707 
708   public:
referenced_vars_iterator(const MemRegion * const * r,const MemRegion * const * originalR)709     explicit referenced_vars_iterator(const MemRegion * const *r,
710                                       const MemRegion * const *originalR)
711         : R(r), OriginalR(originalR) {}
712 
getCapturedRegion()713     const VarRegion *getCapturedRegion() const {
714       return cast<VarRegion>(*R);
715     }
716 
getOriginalRegion()717     const VarRegion *getOriginalRegion() const {
718       return cast<VarRegion>(*OriginalR);
719     }
720 
721     bool operator==(const referenced_vars_iterator &I) const {
722       assert((R == nullptr) == (I.R == nullptr));
723       return I.R == R;
724     }
725 
726     bool operator!=(const referenced_vars_iterator &I) const {
727       assert((R == nullptr) == (I.R == nullptr));
728       return I.R != R;
729     }
730 
731     referenced_vars_iterator &operator++() {
732       ++R;
733       ++OriginalR;
734       return *this;
735     }
736   };
737 
738   /// Return the original region for a captured region, if
739   /// one exists.
740   const VarRegion *getOriginalRegion(const VarRegion *VR) const;
741 
742   referenced_vars_iterator referenced_vars_begin() const;
743   referenced_vars_iterator referenced_vars_end() const;
744 
745   void dumpToStream(raw_ostream &os) const override;
746 
747   void Profile(llvm::FoldingSetNodeID& ID) const override;
748 
classof(const MemRegion * R)749   static bool classof(const MemRegion* R) {
750     return R->getKind() == BlockDataRegionKind;
751   }
752 
753 private:
754   void LazyInitializeReferencedVars();
755   std::pair<const VarRegion *, const VarRegion *>
756   getCaptureRegions(const VarDecl *VD);
757 };
758 
759 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
760 ///  classes, SymbolicRegion represents a region that serves as an alias for
761 ///  either a real region, a NULL pointer, etc.  It essentially is used to
762 ///  map the concept of symbolic values into the domain of regions.  Symbolic
763 ///  regions do not need to be typed.
764 class SymbolicRegion : public SubRegion {
765   friend class MemRegionManager;
766 
767   const SymbolRef sym;
768 
SymbolicRegion(const SymbolRef s,const MemSpaceRegion * sreg)769   SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
770       : SubRegion(sreg, SymbolicRegionKind), sym(s) {
771     // Because pointer arithmetic is represented by ElementRegion layers,
772     // the base symbol here should not contain any arithmetic.
773     assert(s && isa<SymbolData>(s));
774     assert(s->getType()->isAnyPointerType() ||
775            s->getType()->isReferenceType() ||
776            s->getType()->isBlockPointerType());
777 
778     // populateWorklistFromSymbol() relies on this assertion, and needs to be
779     // updated if more cases are introduced.
780     assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
781   }
782 
783 public:
getSymbol()784   SymbolRef getSymbol() const { return sym; }
785 
isBoundable()786   bool isBoundable() const override { return true; }
787 
788   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
789 
790   void Profile(llvm::FoldingSetNodeID& ID) const override;
791 
792   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
793                             SymbolRef sym,
794                             const MemRegion* superRegion);
795 
796   void dumpToStream(raw_ostream &os) const override;
797 
classof(const MemRegion * R)798   static bool classof(const MemRegion* R) {
799     return R->getKind() == SymbolicRegionKind;
800   }
801 };
802 
803 /// StringRegion - Region associated with a StringLiteral.
804 class StringRegion : public TypedValueRegion {
805   friend class MemRegionManager;
806 
807   const StringLiteral *Str;
808 
StringRegion(const StringLiteral * str,const GlobalInternalSpaceRegion * sreg)809   StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
810       : TypedValueRegion(sreg, StringRegionKind), Str(str) {
811     assert(str);
812   }
813 
814   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
815                             const StringLiteral *Str,
816                             const MemRegion *superRegion);
817 
818 public:
getStringLiteral()819   const StringLiteral *getStringLiteral() const { return Str; }
820 
getValueType()821   QualType getValueType() const override { return Str->getType(); }
822 
823   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
824 
isBoundable()825   bool isBoundable() const override { return false; }
826 
Profile(llvm::FoldingSetNodeID & ID)827   void Profile(llvm::FoldingSetNodeID& ID) const override {
828     ProfileRegion(ID, Str, superRegion);
829   }
830 
831   void dumpToStream(raw_ostream &os) const override;
832 
classof(const MemRegion * R)833   static bool classof(const MemRegion* R) {
834     return R->getKind() == StringRegionKind;
835   }
836 };
837 
838 /// The region associated with an ObjCStringLiteral.
839 class ObjCStringRegion : public TypedValueRegion {
840   friend class MemRegionManager;
841 
842   const ObjCStringLiteral *Str;
843 
ObjCStringRegion(const ObjCStringLiteral * str,const GlobalInternalSpaceRegion * sreg)844   ObjCStringRegion(const ObjCStringLiteral *str,
845                    const GlobalInternalSpaceRegion *sreg)
846       : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
847     assert(str);
848   }
849 
850   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
851                             const ObjCStringLiteral *Str,
852                             const MemRegion *superRegion);
853 
854 public:
getObjCStringLiteral()855   const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
856 
getValueType()857   QualType getValueType() const override { return Str->getType(); }
858 
isBoundable()859   bool isBoundable() const override { return false; }
860 
Profile(llvm::FoldingSetNodeID & ID)861   void Profile(llvm::FoldingSetNodeID& ID) const override {
862     ProfileRegion(ID, Str, superRegion);
863   }
864 
865   void dumpToStream(raw_ostream &os) const override;
866 
classof(const MemRegion * R)867   static bool classof(const MemRegion* R) {
868     return R->getKind() == ObjCStringRegionKind;
869   }
870 };
871 
872 /// CompoundLiteralRegion - A memory region representing a compound literal.
873 ///   Compound literals are essentially temporaries that are stack allocated
874 ///   or in the global constant pool.
875 class CompoundLiteralRegion : public TypedValueRegion {
876   friend class MemRegionManager;
877 
878   const CompoundLiteralExpr *CL;
879 
CompoundLiteralRegion(const CompoundLiteralExpr * cl,const MemSpaceRegion * sReg)880   CompoundLiteralRegion(const CompoundLiteralExpr *cl,
881                         const MemSpaceRegion *sReg)
882       : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
883     assert(cl);
884     assert(isa<GlobalInternalSpaceRegion>(sReg) ||
885            isa<StackLocalsSpaceRegion>(sReg));
886   }
887 
888   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
889                             const CompoundLiteralExpr *CL,
890                             const MemRegion* superRegion);
891 
892 public:
getValueType()893   QualType getValueType() const override { return CL->getType(); }
894 
isBoundable()895   bool isBoundable() const override { return !CL->isFileScope(); }
896 
897   void Profile(llvm::FoldingSetNodeID& ID) const override;
898 
899   void dumpToStream(raw_ostream &os) const override;
900 
getLiteralExpr()901   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
902 
classof(const MemRegion * R)903   static bool classof(const MemRegion* R) {
904     return R->getKind() == CompoundLiteralRegionKind;
905   }
906 };
907 
908 class DeclRegion : public TypedValueRegion {
909 protected:
910   const ValueDecl *D;
911 
DeclRegion(const ValueDecl * d,const MemRegion * sReg,Kind k)912   DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
913       : TypedValueRegion(sReg, k), D(d) {
914     assert(classof(this));
915     assert(d);
916   }
917 
918   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
919                       const MemRegion* superRegion, Kind k);
920 
921 public:
getDecl()922   const ValueDecl *getDecl() const { return D; }
923   void Profile(llvm::FoldingSetNodeID& ID) const override;
924 
classof(const MemRegion * R)925   static bool classof(const MemRegion* R) {
926     unsigned k = R->getKind();
927     return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
928   }
929 };
930 
931 class VarRegion : public DeclRegion {
932   friend class MemRegionManager;
933 
934   // Constructors and private methods.
VarRegion(const VarDecl * vd,const MemRegion * sReg)935   VarRegion(const VarDecl *vd, const MemRegion *sReg)
936       : DeclRegion(vd, sReg, VarRegionKind) {
937     // VarRegion appears in unknown space when it's a block variable as seen
938     // from a block using it, when this block is analyzed at top-level.
939     // Other block variables appear within block data regions,
940     // which, unlike everything else on this list, are not memory spaces.
941     assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
942            isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
943   }
944 
ProfileRegion(llvm::FoldingSetNodeID & ID,const VarDecl * VD,const MemRegion * superRegion)945   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
946                             const MemRegion *superRegion) {
947     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
948   }
949 
950 public:
951   void Profile(llvm::FoldingSetNodeID& ID) const override;
952 
getDecl()953   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
954 
955   const StackFrameContext *getStackFrame() const;
956 
getValueType()957   QualType getValueType() const override {
958     // FIXME: We can cache this if needed.
959     return getDecl()->getType();
960   }
961 
962   void dumpToStream(raw_ostream &os) const override;
963 
964   bool canPrintPrettyAsExpr() const override;
965 
966   void printPrettyAsExpr(raw_ostream &os) const override;
967 
classof(const MemRegion * R)968   static bool classof(const MemRegion* R) {
969     return R->getKind() == VarRegionKind;
970   }
971 };
972 
973 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
974 ///  in a call to a C++ method.  This region doesn't represent the object
975 ///  referred to by 'this', but rather 'this' itself.
976 class CXXThisRegion : public TypedValueRegion {
977   friend class MemRegionManager;
978 
CXXThisRegion(const PointerType * thisPointerTy,const StackArgumentsSpaceRegion * sReg)979   CXXThisRegion(const PointerType *thisPointerTy,
980                 const StackArgumentsSpaceRegion *sReg)
981       : TypedValueRegion(sReg, CXXThisRegionKind),
982         ThisPointerTy(thisPointerTy) {
983     assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
984            "Invalid region type!");
985   }
986 
987   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
988                             const PointerType *PT,
989                             const MemRegion *sReg);
990 
991 public:
992   void Profile(llvm::FoldingSetNodeID &ID) const override;
993 
getValueType()994   QualType getValueType() const override {
995     return QualType(ThisPointerTy, 0);
996   }
997 
998   void dumpToStream(raw_ostream &os) const override;
999 
classof(const MemRegion * R)1000   static bool classof(const MemRegion* R) {
1001     return R->getKind() == CXXThisRegionKind;
1002   }
1003 
1004 private:
1005   const PointerType *ThisPointerTy;
1006 };
1007 
1008 class FieldRegion : public DeclRegion {
1009   friend class MemRegionManager;
1010 
FieldRegion(const FieldDecl * fd,const SubRegion * sReg)1011   FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
1012       : DeclRegion(fd, sReg, FieldRegionKind) {}
1013 
ProfileRegion(llvm::FoldingSetNodeID & ID,const FieldDecl * FD,const MemRegion * superRegion)1014   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
1015                             const MemRegion* superRegion) {
1016     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
1017   }
1018 
1019 public:
getDecl()1020   const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
1021 
getValueType()1022   QualType getValueType() const override {
1023     // FIXME: We can cache this if needed.
1024     return getDecl()->getType();
1025   }
1026 
1027   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
1028 
1029   void dumpToStream(raw_ostream &os) const override;
1030 
1031   bool canPrintPretty() const override;
1032   void printPretty(raw_ostream &os) const override;
1033   bool canPrintPrettyAsExpr() const override;
1034   void printPrettyAsExpr(raw_ostream &os) const override;
1035 
classof(const MemRegion * R)1036   static bool classof(const MemRegion* R) {
1037     return R->getKind() == FieldRegionKind;
1038   }
1039 };
1040 
1041 class ObjCIvarRegion : public DeclRegion {
1042   friend class MemRegionManager;
1043 
1044   ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1045 
1046   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1047                             const MemRegion* superRegion);
1048 
1049 public:
1050   const ObjCIvarDecl *getDecl() const;
1051   QualType getValueType() const override;
1052 
1053   bool canPrintPrettyAsExpr() const override;
1054   void printPrettyAsExpr(raw_ostream &os) const override;
1055 
1056   void dumpToStream(raw_ostream &os) const override;
1057 
classof(const MemRegion * R)1058   static bool classof(const MemRegion* R) {
1059     return R->getKind() == ObjCIvarRegionKind;
1060   }
1061 };
1062 
1063 //===----------------------------------------------------------------------===//
1064 // Auxiliary data classes for use with MemRegions.
1065 //===----------------------------------------------------------------------===//
1066 
1067 class RegionRawOffset {
1068   friend class ElementRegion;
1069 
1070   const MemRegion *Region;
1071   CharUnits Offset;
1072 
1073   RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
Region(reg)1074       : Region(reg), Offset(offset) {}
1075 
1076 public:
1077   // FIXME: Eventually support symbolic offsets.
getOffset()1078   CharUnits getOffset() const { return Offset; }
getRegion()1079   const MemRegion *getRegion() const { return Region; }
1080 
1081   void dumpToStream(raw_ostream &os) const;
1082   void dump() const;
1083 };
1084 
1085 /// ElementRegion is used to represent both array elements and casts.
1086 class ElementRegion : public TypedValueRegion {
1087   friend class MemRegionManager;
1088 
1089   QualType ElementType;
1090   NonLoc Index;
1091 
ElementRegion(QualType elementType,NonLoc Idx,const SubRegion * sReg)1092   ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1093       : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1094         Index(Idx) {
1095     assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1096             Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1097            "The index must be signed");
1098     assert(!elementType.isNull() && !elementType->isVoidType() &&
1099            "Invalid region type!");
1100   }
1101 
1102   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1103                             SVal Idx, const MemRegion* superRegion);
1104 
1105 public:
getIndex()1106   NonLoc getIndex() const { return Index; }
1107 
getValueType()1108   QualType getValueType() const override { return ElementType; }
1109 
getElementType()1110   QualType getElementType() const { return ElementType; }
1111 
1112   /// Compute the offset within the array. The array might also be a subobject.
1113   RegionRawOffset getAsArrayOffset() const;
1114 
1115   void dumpToStream(raw_ostream &os) const override;
1116 
1117   void Profile(llvm::FoldingSetNodeID& ID) const override;
1118 
classof(const MemRegion * R)1119   static bool classof(const MemRegion* R) {
1120     return R->getKind() == ElementRegionKind;
1121   }
1122 };
1123 
1124 // C++ temporary object associated with an expression.
1125 class CXXTempObjectRegion : public TypedValueRegion {
1126   friend class MemRegionManager;
1127 
1128   Expr const *Ex;
1129 
CXXTempObjectRegion(Expr const * E,MemSpaceRegion const * sReg)1130   CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1131       : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1132     assert(E);
1133     assert(isa<StackLocalsSpaceRegion>(sReg) ||
1134            isa<GlobalInternalSpaceRegion>(sReg));
1135   }
1136 
1137   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1138                             Expr const *E, const MemRegion *sReg);
1139 
1140 public:
getExpr()1141   const Expr *getExpr() const { return Ex; }
1142 
getValueType()1143   QualType getValueType() const override { return Ex->getType(); }
1144 
1145   void dumpToStream(raw_ostream &os) const override;
1146 
1147   void Profile(llvm::FoldingSetNodeID &ID) const override;
1148 
classof(const MemRegion * R)1149   static bool classof(const MemRegion* R) {
1150     return R->getKind() == CXXTempObjectRegionKind;
1151   }
1152 };
1153 
1154 // CXXBaseObjectRegion represents a base object within a C++ object. It is
1155 // identified by the base class declaration and the region of its parent object.
1156 class CXXBaseObjectRegion : public TypedValueRegion {
1157   friend class MemRegionManager;
1158 
1159   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1160 
CXXBaseObjectRegion(const CXXRecordDecl * RD,bool IsVirtual,const SubRegion * SReg)1161   CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1162                       const SubRegion *SReg)
1163       : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1164     assert(RD);
1165   }
1166 
1167   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1168                             bool IsVirtual, const MemRegion *SReg);
1169 
1170 public:
getDecl()1171   const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
isVirtual()1172   bool isVirtual() const { return Data.getInt(); }
1173 
1174   QualType getValueType() const override;
1175 
1176   void dumpToStream(raw_ostream &os) const override;
1177 
1178   void Profile(llvm::FoldingSetNodeID &ID) const override;
1179 
1180   bool canPrintPrettyAsExpr() const override;
1181 
1182   void printPrettyAsExpr(raw_ostream &os) const override;
1183 
classof(const MemRegion * region)1184   static bool classof(const MemRegion *region) {
1185     return region->getKind() == CXXBaseObjectRegionKind;
1186   }
1187 };
1188 
1189 // CXXDerivedObjectRegion represents a derived-class object that surrounds
1190 // a C++ object. It is identified by the derived class declaration and the
1191 // region of its parent object. It is a bit counter-intuitive (but not otherwise
1192 // unseen) that this region represents a larger segment of memory that its
1193 // super-region.
1194 class CXXDerivedObjectRegion : public TypedValueRegion {
1195   friend class MemRegionManager;
1196 
1197   const CXXRecordDecl *DerivedD;
1198 
CXXDerivedObjectRegion(const CXXRecordDecl * DerivedD,const SubRegion * SReg)1199   CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1200       : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1201     assert(DerivedD);
1202     // In case of a concrete region, it should always be possible to model
1203     // the base-to-derived cast by undoing a previous derived-to-base cast,
1204     // otherwise the cast is most likely ill-formed.
1205     assert(SReg->getSymbolicBase() &&
1206            "Should have unwrapped a base region instead!");
1207   }
1208 
1209   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1210                             const MemRegion *SReg);
1211 
1212 public:
getDecl()1213   const CXXRecordDecl *getDecl() const { return DerivedD; }
1214 
1215   QualType getValueType() const override;
1216 
1217   void dumpToStream(raw_ostream &os) const override;
1218 
1219   void Profile(llvm::FoldingSetNodeID &ID) const override;
1220 
1221   bool canPrintPrettyAsExpr() const override;
1222 
1223   void printPrettyAsExpr(raw_ostream &os) const override;
1224 
classof(const MemRegion * region)1225   static bool classof(const MemRegion *region) {
1226     return region->getKind() == CXXDerivedObjectRegionKind;
1227   }
1228 };
1229 
1230 template<typename RegionTy>
getAs()1231 const RegionTy* MemRegion::getAs() const {
1232   if (const auto *RT = dyn_cast<RegionTy>(this))
1233     return RT;
1234 
1235   return nullptr;
1236 }
1237 
1238 //===----------------------------------------------------------------------===//
1239 // MemRegionManager - Factory object for creating regions.
1240 //===----------------------------------------------------------------------===//
1241 
1242 class MemRegionManager {
1243   ASTContext &C;
1244   llvm::BumpPtrAllocator& A;
1245   llvm::FoldingSet<MemRegion> Regions;
1246 
1247   GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1248   GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1249   GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1250 
1251   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1252     StackLocalsSpaceRegions;
1253   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1254     StackArgumentsSpaceRegions;
1255   llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1256     StaticsGlobalSpaceRegions;
1257 
1258   HeapSpaceRegion *heap = nullptr;
1259   UnknownSpaceRegion *unknown = nullptr;
1260   CodeSpaceRegion *code = nullptr;
1261 
1262 public:
MemRegionManager(ASTContext & c,llvm::BumpPtrAllocator & a)1263   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {}
1264   ~MemRegionManager();
1265 
getContext()1266   ASTContext &getContext() { return C; }
1267 
getAllocator()1268   llvm::BumpPtrAllocator &getAllocator() { return A; }
1269 
1270   /// getStackLocalsRegion - Retrieve the memory region associated with the
1271   ///  specified stack frame.
1272   const StackLocalsSpaceRegion *
1273   getStackLocalsRegion(const StackFrameContext *STC);
1274 
1275   /// getStackArgumentsRegion - Retrieve the memory region associated with
1276   ///  function/method arguments of the specified stack frame.
1277   const StackArgumentsSpaceRegion *
1278   getStackArgumentsRegion(const StackFrameContext *STC);
1279 
1280   /// getGlobalsRegion - Retrieve the memory region associated with
1281   ///  global variables.
1282   const GlobalsSpaceRegion *getGlobalsRegion(
1283       MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1284       const CodeTextRegion *R = nullptr);
1285 
1286   /// getHeapRegion - Retrieve the memory region associated with the
1287   ///  generic "heap".
1288   const HeapSpaceRegion *getHeapRegion();
1289 
1290   /// getUnknownRegion - Retrieve the memory region associated with unknown
1291   /// memory space.
1292   const UnknownSpaceRegion *getUnknownRegion();
1293 
1294   const CodeSpaceRegion *getCodeRegion();
1295 
1296   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1297   const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1298                                       const LocationContext *LC);
1299 
1300   /// getCompoundLiteralRegion - Retrieve the region associated with a
1301   ///  given CompoundLiteral.
1302   const CompoundLiteralRegion*
1303   getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1304                            const LocationContext *LC);
1305 
1306   /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1307   ///  parameter 'this'.
1308   const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1309                                         const LocationContext *LC);
1310 
1311   /// Retrieve or create a "symbolic" memory region.
1312   const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1313 
1314   /// Return a unique symbolic region belonging to heap memory space.
1315   const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1316 
1317   const StringRegion *getStringRegion(const StringLiteral *Str);
1318 
1319   const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1320 
1321   /// getVarRegion - Retrieve or create the memory region associated with
1322   ///  a specified VarDecl and LocationContext.
1323   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1324 
1325   /// getVarRegion - Retrieve or create the memory region associated with
1326   ///  a specified VarDecl and super region.
1327   const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
1328 
1329   /// getElementRegion - Retrieve the memory region associated with the
1330   ///  associated element type, index, and super region.
1331   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1332                                         const SubRegion *superRegion,
1333                                         ASTContext &Ctx);
1334 
getElementRegionWithSuper(const ElementRegion * ER,const SubRegion * superRegion)1335   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1336                                                  const SubRegion *superRegion) {
1337     return getElementRegion(ER->getElementType(), ER->getIndex(),
1338                             superRegion, ER->getContext());
1339   }
1340 
1341   /// getFieldRegion - Retrieve or create the memory region associated with
1342   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1343   ///  memory region (which typically represents the memory representing
1344   ///  a structure or class).
1345   const FieldRegion *getFieldRegion(const FieldDecl *fd,
1346                                     const SubRegion* superRegion);
1347 
getFieldRegionWithSuper(const FieldRegion * FR,const SubRegion * superRegion)1348   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1349                                              const SubRegion *superRegion) {
1350     return getFieldRegion(FR->getDecl(), superRegion);
1351   }
1352 
1353   /// getObjCIvarRegion - Retrieve or create the memory region associated with
1354   ///   a specified Objective-c instance variable.  'superRegion' corresponds
1355   ///   to the containing region (which typically represents the Objective-C
1356   ///   object).
1357   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1358                                           const SubRegion* superRegion);
1359 
1360   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1361                                                     LocationContext const *LC);
1362 
1363   /// Create a CXXBaseObjectRegion with the given base class for region
1364   /// \p Super.
1365   ///
1366   /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1367   const CXXBaseObjectRegion *
1368   getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1369                          bool IsVirtual);
1370 
1371   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1372   /// super region.
1373   const CXXBaseObjectRegion *
getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion * baseReg,const SubRegion * superRegion)1374   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1375                                   const SubRegion *superRegion) {
1376     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1377                                   baseReg->isVirtual());
1378   }
1379 
1380   /// Create a CXXDerivedObjectRegion with the given derived class for region
1381   /// \p Super. This should not be used for casting an existing
1382   /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1383   /// should be removed.
1384   const CXXDerivedObjectRegion *
1385   getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1386                             const SubRegion *Super);
1387 
1388   const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1389   const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1390                                             CanQualType locTy,
1391                                             AnalysisDeclContext *AC);
1392 
1393   /// getBlockDataRegion - Get the memory region associated with an instance
1394   ///  of a block.  Unlike many other MemRegions, the LocationContext*
1395   ///  argument is allowed to be NULL for cases where we have no known
1396   ///  context.
1397   const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1398                                             const LocationContext *lc,
1399                                             unsigned blockCount);
1400 
1401   /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1402   /// by static references. This differs from getCXXTempObjectRegion in the
1403   /// super-region used.
1404   const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1405 
1406 private:
1407   template <typename RegionTy, typename SuperTy,
1408             typename Arg1Ty>
1409   RegionTy* getSubRegion(const Arg1Ty arg1,
1410                          const SuperTy* superRegion);
1411 
1412   template <typename RegionTy, typename SuperTy,
1413             typename Arg1Ty, typename Arg2Ty>
1414   RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1415                          const SuperTy* superRegion);
1416 
1417   template <typename RegionTy, typename SuperTy,
1418             typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1419   RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1420                          const Arg3Ty arg3,
1421                          const SuperTy* superRegion);
1422 
1423   template <typename REG>
1424   const REG* LazyAllocate(REG*& region);
1425 
1426   template <typename REG, typename ARG>
1427   const REG* LazyAllocate(REG*& region, ARG a);
1428 };
1429 
1430 //===----------------------------------------------------------------------===//
1431 // Out-of-line member definitions.
1432 //===----------------------------------------------------------------------===//
1433 
getContext()1434 inline ASTContext &MemRegion::getContext() const {
1435   return getMemRegionManager()->getContext();
1436 }
1437 
1438 //===----------------------------------------------------------------------===//
1439 // Means for storing region/symbol handling traits.
1440 //===----------------------------------------------------------------------===//
1441 
1442 /// Information about invalidation for a particular region/symbol.
1443 class RegionAndSymbolInvalidationTraits {
1444   using StorageTypeForKinds = unsigned char;
1445 
1446   llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1447   llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1448 
1449   using const_region_iterator =
1450       llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1451   using const_symbol_iterator =
1452       llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1453 
1454 public:
1455   /// Describes different invalidation traits.
1456   enum InvalidationKinds {
1457     /// Tells that a region's contents is not changed.
1458     TK_PreserveContents = 0x1,
1459 
1460     /// Suppress pointer-escaping of a region.
1461     TK_SuppressEscape = 0x2,
1462 
1463     // Do not invalidate super region.
1464     TK_DoNotInvalidateSuperRegion = 0x4,
1465 
1466     /// When applied to a MemSpaceRegion, indicates the entire memory space
1467     /// should be invalidated.
1468     TK_EntireMemSpace = 0x8
1469 
1470     // Do not forget to extend StorageTypeForKinds if number of traits exceed
1471     // the number of bits StorageTypeForKinds can store.
1472   };
1473 
1474   void setTrait(SymbolRef Sym, InvalidationKinds IK);
1475   void setTrait(const MemRegion *MR, InvalidationKinds IK);
1476   bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1477   bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1478 };
1479 
1480 //===----------------------------------------------------------------------===//
1481 // Pretty-printing regions.
1482 //===----------------------------------------------------------------------===//
1483 inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1484   R->dumpToStream(os);
1485   return os;
1486 }
1487 
1488 } // namespace ento
1489 
1490 } // namespace clang
1491 
1492 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
1493