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