Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:08

0001 //==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines MemRegion and its subclasses.  MemRegion defines a
0010 //  partially-typed abstraction of memory useful for path-sensitive dataflow
0011 //  analyses.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
0016 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
0017 
0018 #include "clang/AST/ASTContext.h"
0019 #include "clang/AST/CharUnits.h"
0020 #include "clang/AST/Decl.h"
0021 #include "clang/AST/DeclObjC.h"
0022 #include "clang/AST/DeclarationName.h"
0023 #include "clang/AST/Expr.h"
0024 #include "clang/AST/ExprObjC.h"
0025 #include "clang/AST/Type.h"
0026 #include "clang/Analysis/AnalysisDeclContext.h"
0027 #include "clang/Basic/LLVM.h"
0028 #include "clang/Basic/SourceLocation.h"
0029 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0030 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
0031 #include "llvm/ADT/DenseMap.h"
0032 #include "llvm/ADT/FoldingSet.h"
0033 #include "llvm/ADT/PointerIntPair.h"
0034 #include "llvm/ADT/iterator_range.h"
0035 #include "llvm/Support/Allocator.h"
0036 #include "llvm/Support/Casting.h"
0037 #include "llvm/Support/ErrorHandling.h"
0038 #include <cassert>
0039 #include <cstdint>
0040 #include <limits>
0041 #include <optional>
0042 #include <string>
0043 #include <utility>
0044 
0045 namespace clang {
0046 
0047 class AnalysisDeclContext;
0048 class CXXRecordDecl;
0049 class Decl;
0050 class LocationContext;
0051 class StackFrameContext;
0052 
0053 namespace ento {
0054 
0055 class CodeTextRegion;
0056 class MemRegion;
0057 class MemRegionManager;
0058 class MemSpaceRegion;
0059 class SValBuilder;
0060 class SymbolicRegion;
0061 class VarRegion;
0062 
0063 /// Represent a region's offset within the top level base region.
0064 class RegionOffset {
0065   /// The base region.
0066   const MemRegion *R = nullptr;
0067 
0068   /// The bit offset within the base region. Can be negative.
0069   int64_t Offset;
0070 
0071 public:
0072   // We're using a const instead of an enumeration due to the size required;
0073   // Visual Studio will only create enumerations of size int, not long long.
0074   static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
0075 
0076   RegionOffset() = default;
0077   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
0078 
0079   /// It might return null.
0080   const MemRegion *getRegion() const { return R; }
0081 
0082   bool hasSymbolicOffset() const { return Offset == Symbolic; }
0083 
0084   int64_t getOffset() const {
0085     assert(!hasSymbolicOffset());
0086     return Offset;
0087   }
0088 
0089   bool isValid() const { return R; }
0090 };
0091 
0092 //===----------------------------------------------------------------------===//
0093 // Base region classes.
0094 //===----------------------------------------------------------------------===//
0095 
0096 /// MemRegion - The root abstract class for all memory regions.
0097 class MemRegion : public llvm::FoldingSetNode {
0098 public:
0099   enum Kind {
0100 #define REGION(Id, Parent) Id ## Kind,
0101 #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
0102 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
0103 #undef REGION
0104 #undef REGION_RANGE
0105   };
0106 
0107 private:
0108   const Kind kind;
0109   mutable std::optional<RegionOffset> cachedOffset;
0110 
0111 protected:
0112   MemRegion(Kind k) : kind(k) {}
0113   virtual ~MemRegion();
0114 
0115 public:
0116   ASTContext &getContext() const;
0117 
0118   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
0119 
0120   virtual MemRegionManager &getMemRegionManager() const = 0;
0121 
0122   LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const;
0123 
0124   LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const;
0125 
0126   /// Recursively retrieve the region of the most derived class instance of
0127   /// regions of C++ base class instances.
0128   LLVM_ATTRIBUTE_RETURNS_NONNULL
0129   const MemRegion *getMostDerivedObjectRegion() const;
0130 
0131   /// Check if the region is a subregion of the given region.
0132   /// Each region is a subregion of itself.
0133   virtual bool isSubRegionOf(const MemRegion *R) const;
0134 
0135   LLVM_ATTRIBUTE_RETURNS_NONNULL
0136   const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
0137 
0138   /// If this is a symbolic region, returns the region. Otherwise,
0139   /// goes up the base chain looking for the first symbolic base region.
0140   /// It might return null.
0141   const SymbolicRegion *getSymbolicBase() const;
0142 
0143   bool hasStackStorage() const;
0144 
0145   bool hasStackNonParametersStorage() const;
0146 
0147   bool hasStackParametersStorage() const;
0148 
0149   /// Compute the offset within the top level memory object.
0150   RegionOffset getAsOffset() const;
0151 
0152   /// Get a string representation of a region for debug use.
0153   std::string getString() const;
0154 
0155   virtual void dumpToStream(raw_ostream &os) const;
0156 
0157   void dump() const;
0158 
0159   /// Returns true if this region can be printed in a user-friendly way.
0160   virtual bool canPrintPretty() const;
0161 
0162   /// Print the region for use in diagnostics.
0163   virtual void printPretty(raw_ostream &os) const;
0164 
0165   /// Returns true if this region's textual representation can be used
0166   /// as part of a larger expression.
0167   virtual bool canPrintPrettyAsExpr() const;
0168 
0169   /// Print the region as expression.
0170   ///
0171   /// When this region represents a subexpression, the method is for printing
0172   /// an expression containing it.
0173   virtual void printPrettyAsExpr(raw_ostream &os) const;
0174 
0175   Kind getKind() const { return kind; }
0176 
0177   StringRef getKindStr() const;
0178 
0179   template<typename RegionTy> const RegionTy* getAs() const;
0180   template <typename RegionTy>
0181   LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const;
0182 
0183   virtual bool isBoundable() const { return false; }
0184 
0185   /// Get descriptive name for memory region. The name is obtained from
0186   /// the variable/field declaration retrieved from the memory region.
0187   /// Regions that point to an element of an array are returned as: "arr[0]".
0188   /// Regions that point to a struct are returned as: "st.var".
0189   //
0190   /// \param UseQuotes Set if the name should be quoted.
0191   ///
0192   /// \returns variable name for memory region
0193   std::string getDescriptiveName(bool UseQuotes = true) const;
0194 
0195   /// Retrieve source range from memory region. The range retrieval
0196   /// is based on the decl obtained from the memory region.
0197   /// For a VarRegion the range of the base region is returned.
0198   /// For a FieldRegion the range of the field is returned.
0199   /// If no declaration is found, an empty source range is returned.
0200   /// The client is responsible for checking if the returned range is valid.
0201   ///
0202   /// \returns source range for declaration retrieved from memory region
0203   SourceRange sourceRange() const;
0204 };
0205 
0206 /// MemSpaceRegion - A memory region that represents a "memory space";
0207 ///  for example, the set of global variables, the stack frame, etc.
0208 class MemSpaceRegion : public MemRegion {
0209 protected:
0210   MemRegionManager &Mgr;
0211 
0212   MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
0213     assert(classof(this));
0214   }
0215 
0216   MemRegionManager &getMemRegionManager() const override { return Mgr; }
0217 
0218 public:
0219   bool isBoundable() const override { return false; }
0220 
0221   void Profile(llvm::FoldingSetNodeID &ID) const override;
0222 
0223   static bool classof(const MemRegion *R) {
0224     Kind k = R->getKind();
0225     return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
0226   }
0227 };
0228 
0229 /// CodeSpaceRegion - The memory space that holds the executable code of
0230 /// functions and blocks.
0231 class CodeSpaceRegion : public MemSpaceRegion {
0232   friend class MemRegionManager;
0233 
0234   CodeSpaceRegion(MemRegionManager &mgr)
0235       : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
0236 
0237 public:
0238   void dumpToStream(raw_ostream &os) const override;
0239 
0240   static bool classof(const MemRegion *R) {
0241     return R->getKind() == CodeSpaceRegionKind;
0242   }
0243 };
0244 
0245 class GlobalsSpaceRegion : public MemSpaceRegion {
0246   virtual void anchor();
0247 
0248 protected:
0249   GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
0250     assert(classof(this));
0251   }
0252 
0253 public:
0254   static bool classof(const MemRegion *R) {
0255     Kind k = R->getKind();
0256     return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
0257   }
0258 };
0259 
0260 /// The region of the static variables within the current CodeTextRegion
0261 /// scope.
0262 ///
0263 /// Currently, only the static locals are placed there, so we know that these
0264 /// variables do not get invalidated by calls to other functions.
0265 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
0266   friend class MemRegionManager;
0267 
0268   const CodeTextRegion *CR;
0269 
0270   StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr)
0271       : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
0272     assert(cr);
0273   }
0274 
0275 public:
0276   void Profile(llvm::FoldingSetNodeID &ID) const override;
0277 
0278   void dumpToStream(raw_ostream &os) const override;
0279 
0280   LLVM_ATTRIBUTE_RETURNS_NONNULL
0281   const CodeTextRegion *getCodeRegion() const { return CR; }
0282 
0283   static bool classof(const MemRegion *R) {
0284     return R->getKind() == StaticGlobalSpaceRegionKind;
0285   }
0286 };
0287 
0288 /// The region for all the non-static global variables.
0289 ///
0290 /// This class is further split into subclasses for efficient implementation of
0291 /// invalidating a set of related global values as is done in
0292 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
0293 /// globals, we invalidate the whole parent region).
0294 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
0295   void anchor() override;
0296 
0297 protected:
0298   NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
0299       : GlobalsSpaceRegion(mgr, k) {
0300     assert(classof(this));
0301   }
0302 
0303 public:
0304   static bool classof(const MemRegion *R) {
0305     Kind k = R->getKind();
0306     return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
0307            k <= END_NON_STATIC_GLOBAL_MEMSPACES;
0308   }
0309 };
0310 
0311 /// The region containing globals which are defined in system/external
0312 /// headers and are considered modifiable by system calls (ex: errno).
0313 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
0314   friend class MemRegionManager;
0315 
0316   GlobalSystemSpaceRegion(MemRegionManager &mgr)
0317       : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
0318 
0319 public:
0320   void dumpToStream(raw_ostream &os) const override;
0321 
0322   static bool classof(const MemRegion *R) {
0323     return R->getKind() == GlobalSystemSpaceRegionKind;
0324   }
0325 };
0326 
0327 /// The region containing globals which are considered not to be modified
0328 /// or point to data which could be modified as a result of a function call
0329 /// (system or internal). Ex: Const global scalars would be modeled as part of
0330 /// this region. This region also includes most system globals since they have
0331 /// low chance of being modified.
0332 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
0333   friend class MemRegionManager;
0334 
0335   GlobalImmutableSpaceRegion(MemRegionManager &mgr)
0336       : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
0337 
0338 public:
0339   void dumpToStream(raw_ostream &os) const override;
0340 
0341   static bool classof(const MemRegion *R) {
0342     return R->getKind() == GlobalImmutableSpaceRegionKind;
0343   }
0344 };
0345 
0346 /// The region containing globals which can be modified by calls to
0347 /// "internally" defined functions - (for now just) functions other then system
0348 /// calls.
0349 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
0350   friend class MemRegionManager;
0351 
0352   GlobalInternalSpaceRegion(MemRegionManager &mgr)
0353       : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
0354 
0355 public:
0356   void dumpToStream(raw_ostream &os) const override;
0357 
0358   static bool classof(const MemRegion *R) {
0359     return R->getKind() == GlobalInternalSpaceRegionKind;
0360   }
0361 };
0362 
0363 class HeapSpaceRegion : public MemSpaceRegion {
0364   friend class MemRegionManager;
0365 
0366   HeapSpaceRegion(MemRegionManager &mgr)
0367       : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
0368 
0369 public:
0370   void dumpToStream(raw_ostream &os) const override;
0371 
0372   static bool classof(const MemRegion *R) {
0373     return R->getKind() == HeapSpaceRegionKind;
0374   }
0375 };
0376 
0377 class UnknownSpaceRegion : public MemSpaceRegion {
0378   friend class MemRegionManager;
0379 
0380   UnknownSpaceRegion(MemRegionManager &mgr)
0381       : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
0382 
0383 public:
0384   void dumpToStream(raw_ostream &os) const override;
0385 
0386   static bool classof(const MemRegion *R) {
0387     return R->getKind() == UnknownSpaceRegionKind;
0388   }
0389 };
0390 
0391 class StackSpaceRegion : public MemSpaceRegion {
0392   virtual void anchor();
0393 
0394   const StackFrameContext *SFC;
0395 
0396 protected:
0397   StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
0398       : MemSpaceRegion(mgr, k), SFC(sfc) {
0399     assert(classof(this));
0400     assert(sfc);
0401   }
0402 
0403 public:
0404   LLVM_ATTRIBUTE_RETURNS_NONNULL
0405   const StackFrameContext *getStackFrame() const { return SFC; }
0406 
0407   void Profile(llvm::FoldingSetNodeID &ID) const override;
0408 
0409   static bool classof(const MemRegion *R) {
0410     Kind k = R->getKind();
0411     return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
0412   }
0413 };
0414 
0415 class StackLocalsSpaceRegion : public StackSpaceRegion {
0416   friend class MemRegionManager;
0417 
0418   StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
0419       : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
0420 
0421 public:
0422   void dumpToStream(raw_ostream &os) const override;
0423 
0424   static bool classof(const MemRegion *R) {
0425     return R->getKind() == StackLocalsSpaceRegionKind;
0426   }
0427 };
0428 
0429 class StackArgumentsSpaceRegion : public StackSpaceRegion {
0430 private:
0431   friend class MemRegionManager;
0432 
0433   StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
0434       : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
0435 
0436 public:
0437   void dumpToStream(raw_ostream &os) const override;
0438 
0439   static bool classof(const MemRegion *R) {
0440     return R->getKind() == StackArgumentsSpaceRegionKind;
0441   }
0442 };
0443 
0444 /// SubRegion - A region that subsets another larger region.  Most regions
0445 ///  are subclasses of SubRegion.
0446 class SubRegion : public MemRegion {
0447   virtual void anchor();
0448 
0449 protected:
0450   const MemRegion* superRegion;
0451 
0452   SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
0453     assert(classof(this));
0454     assert(sReg);
0455   }
0456 
0457 public:
0458   LLVM_ATTRIBUTE_RETURNS_NONNULL
0459   const MemRegion* getSuperRegion() const {
0460     return superRegion;
0461   }
0462 
0463   MemRegionManager &getMemRegionManager() const override;
0464 
0465   bool isSubRegionOf(const MemRegion* R) const override;
0466 
0467   static bool classof(const MemRegion* R) {
0468     return R->getKind() > END_MEMSPACES;
0469   }
0470 };
0471 
0472 //===----------------------------------------------------------------------===//
0473 // MemRegion subclasses.
0474 //===----------------------------------------------------------------------===//
0475 
0476 /// AllocaRegion - A region that represents an untyped blob of bytes created
0477 ///  by a call to 'alloca'.
0478 class AllocaRegion : public SubRegion {
0479   friend class MemRegionManager;
0480 
0481   // Block counter. Used to distinguish different pieces of memory allocated by
0482   // alloca at the same call site.
0483   unsigned Cnt;
0484 
0485   const Expr *Ex;
0486 
0487   AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
0488       : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
0489     assert(Ex);
0490   }
0491 
0492   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
0493                             unsigned Cnt, const MemRegion *superRegion);
0494 
0495 public:
0496   LLVM_ATTRIBUTE_RETURNS_NONNULL
0497   const Expr *getExpr() const { return Ex; }
0498 
0499   bool isBoundable() const override { return true; }
0500 
0501   void Profile(llvm::FoldingSetNodeID& ID) const override;
0502 
0503   void dumpToStream(raw_ostream &os) const override;
0504 
0505   static bool classof(const MemRegion* R) {
0506     return R->getKind() == AllocaRegionKind;
0507   }
0508 };
0509 
0510 /// TypedRegion - An abstract class representing regions that are typed.
0511 class TypedRegion : public SubRegion {
0512   void anchor() override;
0513 
0514 protected:
0515   TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
0516     assert(classof(this));
0517   }
0518 
0519 public:
0520   virtual QualType getLocationType() const = 0;
0521 
0522   QualType getDesugaredLocationType(ASTContext &Context) const {
0523     return getLocationType().getDesugaredType(Context);
0524   }
0525 
0526   bool isBoundable() const override { return true; }
0527 
0528   static bool classof(const MemRegion* R) {
0529     unsigned k = R->getKind();
0530     return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
0531   }
0532 };
0533 
0534 /// TypedValueRegion - An abstract class representing regions having a typed value.
0535 class TypedValueRegion : public TypedRegion {
0536   void anchor() override;
0537 
0538 protected:
0539   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
0540     assert(classof(this));
0541   }
0542 
0543 public:
0544   virtual QualType getValueType() const = 0;
0545 
0546   QualType getLocationType() const override {
0547     // FIXME: We can possibly optimize this later to cache this value.
0548     QualType T = getValueType();
0549     ASTContext &ctx = getContext();
0550     if (T->getAs<ObjCObjectType>())
0551       return ctx.getObjCObjectPointerType(T);
0552     return ctx.getPointerType(getValueType());
0553   }
0554 
0555   QualType getDesugaredValueType(ASTContext &Context) const {
0556     QualType T = getValueType();
0557     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
0558   }
0559 
0560   static bool classof(const MemRegion* R) {
0561     unsigned k = R->getKind();
0562     return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
0563   }
0564 };
0565 
0566 class CodeTextRegion : public TypedRegion {
0567   void anchor() override;
0568 
0569 protected:
0570   CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
0571     assert(classof(this));
0572   }
0573 
0574 public:
0575   bool isBoundable() const override { return false; }
0576 
0577   static bool classof(const MemRegion* R) {
0578     Kind k = R->getKind();
0579     return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS;
0580   }
0581 };
0582 
0583 /// FunctionCodeRegion - A region that represents code texts of function.
0584 class FunctionCodeRegion : public CodeTextRegion {
0585   friend class MemRegionManager;
0586 
0587   const NamedDecl *FD;
0588 
0589   FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
0590       : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
0591     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
0592   }
0593 
0594   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
0595                             const MemRegion*);
0596 
0597 public:
0598   QualType getLocationType() const override {
0599     const ASTContext &Ctx = getContext();
0600     if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
0601       return Ctx.getPointerType(D->getType());
0602     }
0603 
0604     assert(isa<ObjCMethodDecl>(FD));
0605     assert(false && "Getting the type of ObjCMethod is not supported yet");
0606 
0607     // TODO: We might want to return a different type here (ex: id (*ty)(...))
0608     //       depending on how it is used.
0609     return {};
0610   }
0611 
0612   const NamedDecl *getDecl() const {
0613     return FD;
0614   }
0615 
0616   void dumpToStream(raw_ostream &os) const override;
0617 
0618   void Profile(llvm::FoldingSetNodeID& ID) const override;
0619 
0620   static bool classof(const MemRegion* R) {
0621     return R->getKind() == FunctionCodeRegionKind;
0622   }
0623 };
0624 
0625 /// BlockCodeRegion - A region that represents code texts of blocks (closures).
0626 ///  Blocks are represented with two kinds of regions.  BlockCodeRegions
0627 ///  represent the "code", while BlockDataRegions represent instances of blocks,
0628 ///  which correspond to "code+data".  The distinction is important, because
0629 ///  like a closure a block captures the values of externally referenced
0630 ///  variables.
0631 class BlockCodeRegion : public CodeTextRegion {
0632   friend class MemRegionManager;
0633 
0634   const BlockDecl *BD;
0635   AnalysisDeclContext *AC;
0636   CanQualType locTy;
0637 
0638   BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
0639                   AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
0640       : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
0641     assert(bd);
0642     assert(ac);
0643     assert(lTy->getTypePtr()->isBlockPointerType());
0644   }
0645 
0646   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
0647                             CanQualType, const AnalysisDeclContext*,
0648                             const MemRegion*);
0649 
0650 public:
0651   QualType getLocationType() const override {
0652     return locTy;
0653   }
0654 
0655   LLVM_ATTRIBUTE_RETURNS_NONNULL
0656   const BlockDecl *getDecl() const {
0657     return BD;
0658   }
0659 
0660   LLVM_ATTRIBUTE_RETURNS_NONNULL
0661   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
0662 
0663   void dumpToStream(raw_ostream &os) const override;
0664 
0665   void Profile(llvm::FoldingSetNodeID& ID) const override;
0666 
0667   static bool classof(const MemRegion* R) {
0668     return R->getKind() == BlockCodeRegionKind;
0669   }
0670 };
0671 
0672 /// BlockDataRegion - A region that represents a block instance.
0673 ///  Blocks are represented with two kinds of regions.  BlockCodeRegions
0674 ///  represent the "code", while BlockDataRegions represent instances of blocks,
0675 ///  which correspond to "code+data".  The distinction is important, because
0676 ///  like a closure a block captures the values of externally referenced
0677 ///  variables.
0678 class BlockDataRegion : public TypedRegion {
0679   friend class MemRegionManager;
0680 
0681   const BlockCodeRegion *BC;
0682   const LocationContext *LC; // Can be null
0683   unsigned BlockCount;
0684   void *ReferencedVars = nullptr;
0685   void *OriginalVars = nullptr;
0686 
0687   BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
0688                   unsigned count, const MemSpaceRegion *sreg)
0689       : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
0690         BlockCount(count) {
0691     assert(bc);
0692     assert(bc->getDecl());
0693     assert(lc);
0694     assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
0695            isa<StackLocalsSpaceRegion>(sreg) ||
0696            isa<UnknownSpaceRegion>(sreg));
0697   }
0698 
0699   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
0700                             const LocationContext *, unsigned,
0701                             const MemRegion *);
0702 
0703 public:
0704   LLVM_ATTRIBUTE_RETURNS_NONNULL
0705   const BlockCodeRegion *getCodeRegion() const { return BC; }
0706 
0707   LLVM_ATTRIBUTE_RETURNS_NONNULL
0708   const BlockDecl *getDecl() const { return BC->getDecl(); }
0709 
0710   QualType getLocationType() const override { return BC->getLocationType(); }
0711 
0712   class referenced_vars_iterator {
0713     const MemRegion * const *R;
0714     const MemRegion * const *OriginalR;
0715 
0716   public:
0717     explicit referenced_vars_iterator(const MemRegion * const *r,
0718                                       const MemRegion * const *originalR)
0719         : R(r), OriginalR(originalR) {}
0720 
0721     LLVM_ATTRIBUTE_RETURNS_NONNULL
0722     const VarRegion *getCapturedRegion() const {
0723       return cast<VarRegion>(*R);
0724     }
0725 
0726     LLVM_ATTRIBUTE_RETURNS_NONNULL
0727     const VarRegion *getOriginalRegion() const {
0728       return cast<VarRegion>(*OriginalR);
0729     }
0730 
0731     bool operator==(const referenced_vars_iterator &I) const {
0732       assert((R == nullptr) == (I.R == nullptr));
0733       return I.R == R;
0734     }
0735 
0736     bool operator!=(const referenced_vars_iterator &I) const {
0737       assert((R == nullptr) == (I.R == nullptr));
0738       return I.R != R;
0739     }
0740 
0741     referenced_vars_iterator &operator++() {
0742       ++R;
0743       ++OriginalR;
0744       return *this;
0745     }
0746 
0747     // This isn't really a conventional iterator.
0748     // We just implement the deref as a no-op for now to make range-based for
0749     // loops work.
0750     const referenced_vars_iterator &operator*() const { return *this; }
0751   };
0752 
0753   /// Return the original region for a captured region, if
0754   /// one exists. It might return null.
0755   const VarRegion *getOriginalRegion(const VarRegion *VR) const;
0756 
0757   referenced_vars_iterator referenced_vars_begin() const;
0758   referenced_vars_iterator referenced_vars_end() const;
0759   llvm::iterator_range<referenced_vars_iterator> referenced_vars() const;
0760 
0761   void dumpToStream(raw_ostream &os) const override;
0762 
0763   void Profile(llvm::FoldingSetNodeID& ID) const override;
0764 
0765   static bool classof(const MemRegion* R) {
0766     return R->getKind() == BlockDataRegionKind;
0767   }
0768 
0769 private:
0770   void LazyInitializeReferencedVars();
0771   std::pair<const VarRegion *, const VarRegion *>
0772   getCaptureRegions(const VarDecl *VD);
0773 };
0774 
0775 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
0776 ///  classes, SymbolicRegion represents a region that serves as an alias for
0777 ///  either a real region, a NULL pointer, etc.  It essentially is used to
0778 ///  map the concept of symbolic values into the domain of regions.  Symbolic
0779 ///  regions do not need to be typed.
0780 class SymbolicRegion : public SubRegion {
0781   friend class MemRegionManager;
0782 
0783   const SymbolRef sym;
0784 
0785   SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
0786       : SubRegion(sreg, SymbolicRegionKind), sym(s) {
0787     // Because pointer arithmetic is represented by ElementRegion layers,
0788     // the base symbol here should not contain any arithmetic.
0789     assert(isa_and_nonnull<SymbolData>(s));
0790     assert(s->getType()->isAnyPointerType() ||
0791            s->getType()->isReferenceType() ||
0792            s->getType()->isBlockPointerType());
0793     assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) ||
0794            isa<GlobalSystemSpaceRegion>(sreg));
0795   }
0796 
0797 public:
0798   /// It might return null.
0799   SymbolRef getSymbol() const { return sym; }
0800 
0801   /// Gets the type of the wrapped symbol.
0802   /// This type might not be accurate at all times - it's just our best guess.
0803   /// Consider these cases:
0804   ///   void foo(void *data, char *str, base *obj) {...}
0805   /// The type of the pointee of `data` is of course not `void`, yet that's our
0806   /// best guess. `str` might point to any object and `obj` might point to some
0807   /// derived instance. `TypedRegions` other hand are representing the cases
0808   /// when we actually know their types.
0809   QualType getPointeeStaticType() const {
0810     return sym->getType()->getPointeeType();
0811   }
0812 
0813   bool isBoundable() const override { return true; }
0814 
0815   void Profile(llvm::FoldingSetNodeID& ID) const override;
0816 
0817   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
0818                             SymbolRef sym,
0819                             const MemRegion* superRegion);
0820 
0821   void dumpToStream(raw_ostream &os) const override;
0822 
0823   static bool classof(const MemRegion* R) {
0824     return R->getKind() == SymbolicRegionKind;
0825   }
0826 };
0827 
0828 /// StringRegion - Region associated with a StringLiteral.
0829 class StringRegion : public TypedValueRegion {
0830   friend class MemRegionManager;
0831 
0832   const StringLiteral *Str;
0833 
0834   StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
0835       : TypedValueRegion(sreg, StringRegionKind), Str(str) {
0836     assert(str);
0837   }
0838 
0839   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
0840                             const StringLiteral *Str,
0841                             const MemRegion *superRegion);
0842 
0843 public:
0844   LLVM_ATTRIBUTE_RETURNS_NONNULL
0845   const StringLiteral *getStringLiteral() const { return Str; }
0846 
0847   QualType getValueType() const override { return Str->getType(); }
0848 
0849   bool isBoundable() const override { return false; }
0850 
0851   void Profile(llvm::FoldingSetNodeID& ID) const override {
0852     ProfileRegion(ID, Str, superRegion);
0853   }
0854 
0855   void dumpToStream(raw_ostream &os) const override;
0856 
0857   static bool classof(const MemRegion* R) {
0858     return R->getKind() == StringRegionKind;
0859   }
0860 };
0861 
0862 /// The region associated with an ObjCStringLiteral.
0863 class ObjCStringRegion : public TypedValueRegion {
0864   friend class MemRegionManager;
0865 
0866   const ObjCStringLiteral *Str;
0867 
0868   ObjCStringRegion(const ObjCStringLiteral *str,
0869                    const GlobalInternalSpaceRegion *sreg)
0870       : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
0871     assert(str);
0872   }
0873 
0874   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
0875                             const ObjCStringLiteral *Str,
0876                             const MemRegion *superRegion);
0877 
0878 public:
0879   LLVM_ATTRIBUTE_RETURNS_NONNULL
0880   const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
0881 
0882   QualType getValueType() const override { return Str->getType(); }
0883 
0884   bool isBoundable() const override { return false; }
0885 
0886   void Profile(llvm::FoldingSetNodeID& ID) const override {
0887     ProfileRegion(ID, Str, superRegion);
0888   }
0889 
0890   void dumpToStream(raw_ostream &os) const override;
0891 
0892   static bool classof(const MemRegion* R) {
0893     return R->getKind() == ObjCStringRegionKind;
0894   }
0895 };
0896 
0897 /// CompoundLiteralRegion - A memory region representing a compound literal.
0898 ///   Compound literals are essentially temporaries that are stack allocated
0899 ///   or in the global constant pool.
0900 class CompoundLiteralRegion : public TypedValueRegion {
0901   friend class MemRegionManager;
0902 
0903   const CompoundLiteralExpr *CL;
0904 
0905   CompoundLiteralRegion(const CompoundLiteralExpr *cl,
0906                         const MemSpaceRegion *sReg)
0907       : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
0908     assert(cl);
0909     assert(isa<GlobalInternalSpaceRegion>(sReg) ||
0910            isa<StackLocalsSpaceRegion>(sReg));
0911   }
0912 
0913   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
0914                             const CompoundLiteralExpr *CL,
0915                             const MemRegion* superRegion);
0916 
0917 public:
0918   QualType getValueType() const override { return CL->getType(); }
0919 
0920   bool isBoundable() const override { return !CL->isFileScope(); }
0921 
0922   void Profile(llvm::FoldingSetNodeID& ID) const override;
0923 
0924   void dumpToStream(raw_ostream &os) const override;
0925 
0926   LLVM_ATTRIBUTE_RETURNS_NONNULL
0927   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
0928 
0929   static bool classof(const MemRegion* R) {
0930     return R->getKind() == CompoundLiteralRegionKind;
0931   }
0932 };
0933 
0934 class DeclRegion : public TypedValueRegion {
0935 protected:
0936   DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
0937     assert(classof(this));
0938   }
0939 
0940 public:
0941   // TODO what does this return?
0942   virtual const ValueDecl *getDecl() const = 0;
0943 
0944   static bool classof(const MemRegion* R) {
0945     unsigned k = R->getKind();
0946     return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
0947   }
0948 };
0949 
0950 class VarRegion : public DeclRegion {
0951   friend class MemRegionManager;
0952 
0953 protected:
0954   // Constructors and protected methods.
0955   VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) {
0956     // VarRegion appears in unknown space when it's a block variable as seen
0957     // from a block using it, when this block is analyzed at top-level.
0958     // Other block variables appear within block data regions,
0959     // which, unlike everything else on this list, are not memory spaces.
0960     assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
0961            isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
0962   }
0963 
0964 public:
0965   // TODO what does this return?
0966   const VarDecl *getDecl() const override = 0;
0967 
0968   /// It might return null.
0969   const StackFrameContext *getStackFrame() const;
0970 
0971   QualType getValueType() const override {
0972     // FIXME: We can cache this if needed.
0973     return getDecl()->getType();
0974   }
0975 
0976   static bool classof(const MemRegion *R) {
0977     unsigned k = R->getKind();
0978     return k >= BEGIN_VAR_REGIONS && k <= END_VAR_REGIONS;
0979   }
0980 };
0981 
0982 class NonParamVarRegion : public VarRegion {
0983   friend class MemRegionManager;
0984 
0985   const VarDecl *VD;
0986 
0987   // Constructors and private methods.
0988   NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg)
0989       : VarRegion(sReg, NonParamVarRegionKind), VD(vd) {
0990     // VarRegion appears in unknown space when it's a block variable as seen
0991     // from a block using it, when this block is analyzed at top-level.
0992     // Other block variables appear within block data regions,
0993     // which, unlike everything else on this list, are not memory spaces.
0994     assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
0995            isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
0996     assert(vd);
0997   }
0998 
0999   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD,
1000                             const MemRegion *superRegion);
1001 
1002 public:
1003   void Profile(llvm::FoldingSetNodeID &ID) const override;
1004 
1005   LLVM_ATTRIBUTE_RETURNS_NONNULL
1006   const VarDecl *getDecl() const override { return VD; }
1007 
1008   QualType getValueType() const override {
1009     // FIXME: We can cache this if needed.
1010     return getDecl()->getType();
1011   }
1012 
1013   void dumpToStream(raw_ostream &os) const override;
1014 
1015   bool canPrintPrettyAsExpr() const override;
1016 
1017   void printPrettyAsExpr(raw_ostream &os) const override;
1018 
1019   static bool classof(const MemRegion* R) {
1020     return R->getKind() == NonParamVarRegionKind;
1021   }
1022 };
1023 
1024 /// ParamVarRegion - Represents a region for paremters. Only parameters of the
1025 /// function in the current stack frame are represented as `ParamVarRegion`s.
1026 /// Parameters of top-level analyzed functions as well as captured paremeters
1027 /// by lambdas and blocks are repesented as `VarRegion`s.
1028 
1029 // FIXME: `ParamVarRegion` only supports parameters of functions, C++
1030 // constructors, blocks and Objective-C methods with existing `Decl`. Upon
1031 // implementing stack frame creations for functions without decl (functions
1032 // passed by unknown function pointer) methods of `ParamVarRegion` must be
1033 // updated.
1034 class ParamVarRegion : public VarRegion {
1035   friend class MemRegionManager;
1036 
1037   const Expr *OriginExpr;
1038   unsigned Index;
1039 
1040   ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg)
1041       : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) {
1042     assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame());
1043     assert(OriginExpr);
1044   }
1045 
1046   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
1047                             unsigned Idx, const MemRegion *SReg);
1048 
1049 public:
1050   LLVM_ATTRIBUTE_RETURNS_NONNULL
1051   const Expr *getOriginExpr() const { return OriginExpr; }
1052   unsigned getIndex() const { return Index; }
1053 
1054   void Profile(llvm::FoldingSetNodeID& ID) const override;
1055 
1056   void dumpToStream(raw_ostream &os) const override;
1057 
1058   QualType getValueType() const override;
1059 
1060   /// TODO: What does this return?
1061   const ParmVarDecl *getDecl() const override;
1062 
1063   bool canPrintPrettyAsExpr() const override;
1064   void printPrettyAsExpr(raw_ostream &os) const override;
1065 
1066   static bool classof(const MemRegion *R) {
1067     return R->getKind() == ParamVarRegionKind;
1068   }
1069 };
1070 
1071 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
1072 ///  in a call to a C++ method.  This region doesn't represent the object
1073 ///  referred to by 'this', but rather 'this' itself.
1074 class CXXThisRegion : public TypedValueRegion {
1075   friend class MemRegionManager;
1076 
1077   CXXThisRegion(const PointerType *thisPointerTy,
1078                 const StackArgumentsSpaceRegion *sReg)
1079       : TypedValueRegion(sReg, CXXThisRegionKind),
1080         ThisPointerTy(thisPointerTy) {
1081     assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
1082            "Invalid region type!");
1083   }
1084 
1085   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1086                             const PointerType *PT,
1087                             const MemRegion *sReg);
1088 
1089 public:
1090   void Profile(llvm::FoldingSetNodeID &ID) const override;
1091 
1092   QualType getValueType() const override {
1093     return QualType(ThisPointerTy, 0);
1094   }
1095 
1096   void dumpToStream(raw_ostream &os) const override;
1097 
1098   static bool classof(const MemRegion* R) {
1099     return R->getKind() == CXXThisRegionKind;
1100   }
1101 
1102 private:
1103   const PointerType *ThisPointerTy;
1104 };
1105 
1106 class FieldRegion : public DeclRegion {
1107   friend class MemRegionManager;
1108 
1109   const FieldDecl *FD;
1110 
1111   FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
1112       : DeclRegion(sReg, FieldRegionKind), FD(fd) {
1113     assert(FD);
1114   }
1115 
1116   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD,
1117                             const MemRegion* superRegion) {
1118     ID.AddInteger(static_cast<unsigned>(FieldRegionKind));
1119     ID.AddPointer(FD);
1120     ID.AddPointer(superRegion);
1121   }
1122 
1123 public:
1124   LLVM_ATTRIBUTE_RETURNS_NONNULL
1125   const FieldDecl *getDecl() const override { return FD; }
1126 
1127   void Profile(llvm::FoldingSetNodeID &ID) const override;
1128 
1129   QualType getValueType() const override {
1130     // FIXME: We can cache this if needed.
1131     return getDecl()->getType();
1132   }
1133 
1134   void dumpToStream(raw_ostream &os) const override;
1135 
1136   bool canPrintPretty() const override;
1137   void printPretty(raw_ostream &os) const override;
1138   bool canPrintPrettyAsExpr() const override;
1139   void printPrettyAsExpr(raw_ostream &os) const override;
1140 
1141   static bool classof(const MemRegion* R) {
1142     return R->getKind() == FieldRegionKind;
1143   }
1144 };
1145 
1146 class ObjCIvarRegion : public DeclRegion {
1147   friend class MemRegionManager;
1148 
1149   const ObjCIvarDecl *IVD;
1150 
1151   ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1152 
1153   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1154                             const MemRegion* superRegion);
1155 
1156 public:
1157   LLVM_ATTRIBUTE_RETURNS_NONNULL
1158   const ObjCIvarDecl *getDecl() const override;
1159 
1160   void Profile(llvm::FoldingSetNodeID& ID) const override;
1161 
1162   QualType getValueType() const override;
1163 
1164   bool canPrintPrettyAsExpr() const override;
1165   void printPrettyAsExpr(raw_ostream &os) const override;
1166 
1167   void dumpToStream(raw_ostream &os) const override;
1168 
1169   static bool classof(const MemRegion* R) {
1170     return R->getKind() == ObjCIvarRegionKind;
1171   }
1172 };
1173 
1174 //===----------------------------------------------------------------------===//
1175 // Auxiliary data classes for use with MemRegions.
1176 //===----------------------------------------------------------------------===//
1177 
1178 class RegionRawOffset {
1179   friend class ElementRegion;
1180 
1181   const MemRegion *Region;
1182   CharUnits Offset;
1183 
1184   RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1185       : Region(reg), Offset(offset) {}
1186 
1187 public:
1188   // FIXME: Eventually support symbolic offsets.
1189   CharUnits getOffset() const { return Offset; }
1190 
1191   // It might return null.
1192   const MemRegion *getRegion() const { return Region; }
1193 
1194   void dumpToStream(raw_ostream &os) const;
1195   void dump() const;
1196 };
1197 
1198 /// ElementRegion is used to represent both array elements and casts.
1199 class ElementRegion : public TypedValueRegion {
1200   friend class MemRegionManager;
1201 
1202   QualType ElementType;
1203   NonLoc Index;
1204 
1205   ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1206       : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1207         Index(Idx) {
1208     assert((!isa<nonloc::ConcreteInt>(Idx) ||
1209             Idx.castAs<nonloc::ConcreteInt>().getValue()->isSigned()) &&
1210            "The index must be signed");
1211     assert(!elementType.isNull() && !elementType->isVoidType() &&
1212            "Invalid region type!");
1213   }
1214 
1215   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1216                             SVal Idx, const MemRegion* superRegion);
1217 
1218 public:
1219   NonLoc getIndex() const { return Index; }
1220 
1221   QualType getValueType() const override { return ElementType; }
1222 
1223   QualType getElementType() const { return ElementType; }
1224 
1225   /// Compute the offset within the array. The array might also be a subobject.
1226   RegionRawOffset getAsArrayOffset() const;
1227 
1228   void dumpToStream(raw_ostream &os) const override;
1229 
1230   void Profile(llvm::FoldingSetNodeID& ID) const override;
1231 
1232   static bool classof(const MemRegion* R) {
1233     return R->getKind() == ElementRegionKind;
1234   }
1235 };
1236 
1237 // C++ temporary object associated with an expression.
1238 class CXXTempObjectRegion : public TypedValueRegion {
1239   friend class MemRegionManager;
1240 
1241   Expr const *Ex;
1242 
1243   CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1244       : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1245     assert(E);
1246     assert(isa<StackLocalsSpaceRegion>(sReg));
1247   }
1248 
1249   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1250                             Expr const *E, const MemRegion *sReg);
1251 
1252 public:
1253   LLVM_ATTRIBUTE_RETURNS_NONNULL
1254   const Expr *getExpr() const { return Ex; }
1255 
1256   LLVM_ATTRIBUTE_RETURNS_NONNULL
1257   const StackFrameContext *getStackFrame() const;
1258 
1259   QualType getValueType() const override { return Ex->getType(); }
1260 
1261   void dumpToStream(raw_ostream &os) const override;
1262 
1263   void Profile(llvm::FoldingSetNodeID &ID) const override;
1264 
1265   static bool classof(const MemRegion* R) {
1266     return R->getKind() == CXXTempObjectRegionKind;
1267   }
1268 };
1269 
1270 // C++ temporary object that have lifetime extended to lifetime of the
1271 // variable. Usually they represent temporary bounds to reference variables.
1272 class CXXLifetimeExtendedObjectRegion : public TypedValueRegion {
1273   friend class MemRegionManager;
1274 
1275   Expr const *Ex;
1276   ValueDecl const *ExD;
1277 
1278   CXXLifetimeExtendedObjectRegion(Expr const *E, ValueDecl const *D,
1279                                   MemSpaceRegion const *sReg)
1280       : TypedValueRegion(sReg, CXXLifetimeExtendedObjectRegionKind), Ex(E),
1281         ExD(D) {
1282     assert(E);
1283     assert(D);
1284     assert((isa<StackLocalsSpaceRegion, GlobalInternalSpaceRegion>(sReg)));
1285   }
1286 
1287   static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E,
1288                             ValueDecl const *D, const MemRegion *sReg);
1289 
1290 public:
1291   LLVM_ATTRIBUTE_RETURNS_NONNULL
1292   const Expr *getExpr() const { return Ex; }
1293   LLVM_ATTRIBUTE_RETURNS_NONNULL
1294   const ValueDecl *getExtendingDecl() const { return ExD; }
1295   /// It might return null.
1296   const StackFrameContext *getStackFrame() const;
1297 
1298   QualType getValueType() const override { return Ex->getType(); }
1299 
1300   void dumpToStream(raw_ostream &os) const override;
1301 
1302   void Profile(llvm::FoldingSetNodeID &ID) const override;
1303 
1304   static bool classof(const MemRegion *R) {
1305     return R->getKind() == CXXLifetimeExtendedObjectRegionKind;
1306   }
1307 };
1308 
1309 // CXXBaseObjectRegion represents a base object within a C++ object. It is
1310 // identified by the base class declaration and the region of its parent object.
1311 class CXXBaseObjectRegion : public TypedValueRegion {
1312   friend class MemRegionManager;
1313 
1314   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1315 
1316   CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1317                       const SubRegion *SReg)
1318       : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1319     assert(RD);
1320   }
1321 
1322   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1323                             bool IsVirtual, const MemRegion *SReg);
1324 
1325 public:
1326   LLVM_ATTRIBUTE_RETURNS_NONNULL
1327   const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1328   bool isVirtual() const { return Data.getInt(); }
1329 
1330   QualType getValueType() const override;
1331 
1332   void dumpToStream(raw_ostream &os) const override;
1333 
1334   void Profile(llvm::FoldingSetNodeID &ID) const override;
1335 
1336   bool canPrintPrettyAsExpr() const override;
1337 
1338   void printPrettyAsExpr(raw_ostream &os) const override;
1339 
1340   static bool classof(const MemRegion *region) {
1341     return region->getKind() == CXXBaseObjectRegionKind;
1342   }
1343 };
1344 
1345 // CXXDerivedObjectRegion represents a derived-class object that surrounds
1346 // a C++ object. It is identified by the derived class declaration and the
1347 // region of its parent object. It is a bit counter-intuitive (but not otherwise
1348 // unseen) that this region represents a larger segment of memory that its
1349 // super-region.
1350 class CXXDerivedObjectRegion : public TypedValueRegion {
1351   friend class MemRegionManager;
1352 
1353   const CXXRecordDecl *DerivedD;
1354 
1355   CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1356       : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1357     assert(DerivedD);
1358     // In case of a concrete region, it should always be possible to model
1359     // the base-to-derived cast by undoing a previous derived-to-base cast,
1360     // otherwise the cast is most likely ill-formed.
1361     assert(SReg->getSymbolicBase() &&
1362            "Should have unwrapped a base region instead!");
1363   }
1364 
1365   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1366                             const MemRegion *SReg);
1367 
1368 public:
1369   LLVM_ATTRIBUTE_RETURNS_NONNULL
1370   const CXXRecordDecl *getDecl() const { return DerivedD; }
1371 
1372   QualType getValueType() const override;
1373 
1374   void dumpToStream(raw_ostream &os) const override;
1375 
1376   void Profile(llvm::FoldingSetNodeID &ID) const override;
1377 
1378   bool canPrintPrettyAsExpr() const override;
1379 
1380   void printPrettyAsExpr(raw_ostream &os) const override;
1381 
1382   static bool classof(const MemRegion *region) {
1383     return region->getKind() == CXXDerivedObjectRegionKind;
1384   }
1385 };
1386 
1387 template<typename RegionTy>
1388 const RegionTy* MemRegion::getAs() const {
1389   if (const auto *RT = dyn_cast<RegionTy>(this))
1390     return RT;
1391 
1392   return nullptr;
1393 }
1394 
1395 template <typename RegionTy>
1396 LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const {
1397   return cast<RegionTy>(this);
1398 }
1399 
1400 //===----------------------------------------------------------------------===//
1401 // MemRegionManager - Factory object for creating regions.
1402 //===----------------------------------------------------------------------===//
1403 
1404 class MemRegionManager {
1405   ASTContext &Ctx;
1406   llvm::BumpPtrAllocator& A;
1407 
1408   llvm::FoldingSet<MemRegion> Regions;
1409 
1410   GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1411   GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1412   GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1413 
1414   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1415     StackLocalsSpaceRegions;
1416   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1417     StackArgumentsSpaceRegions;
1418   llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1419     StaticsGlobalSpaceRegions;
1420 
1421   HeapSpaceRegion *heap = nullptr;
1422   UnknownSpaceRegion *unknown = nullptr;
1423   CodeSpaceRegion *code = nullptr;
1424 
1425 public:
1426   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1427   ~MemRegionManager();
1428 
1429   ASTContext &getContext() { return Ctx; }
1430   const ASTContext &getContext() const { return Ctx; }
1431 
1432   llvm::BumpPtrAllocator &getAllocator() { return A; }
1433 
1434   /// \returns The static size in bytes of the region \p MR.
1435   /// \note The region \p MR must be a 'SubRegion'.
1436   DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
1437                                      SValBuilder &SVB) const;
1438 
1439   /// getStackLocalsRegion - Retrieve the memory region associated with the
1440   ///  specified stack frame.
1441   const StackLocalsSpaceRegion *
1442   getStackLocalsRegion(const StackFrameContext *STC);
1443 
1444   /// getStackArgumentsRegion - Retrieve the memory region associated with
1445   ///  function/method arguments of the specified stack frame.
1446   const StackArgumentsSpaceRegion *
1447   getStackArgumentsRegion(const StackFrameContext *STC);
1448 
1449   /// getGlobalsRegion - Retrieve the memory region associated with
1450   ///  global variables.
1451   const GlobalsSpaceRegion *getGlobalsRegion(
1452       MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1453       const CodeTextRegion *R = nullptr);
1454 
1455   /// getHeapRegion - Retrieve the memory region associated with the
1456   ///  generic "heap".
1457   const HeapSpaceRegion *getHeapRegion();
1458 
1459   /// getUnknownRegion - Retrieve the memory region associated with unknown
1460   /// memory space.
1461   const UnknownSpaceRegion *getUnknownRegion();
1462 
1463   const CodeSpaceRegion *getCodeRegion();
1464 
1465   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1466   const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1467                                       const LocationContext *LC);
1468 
1469   /// getCompoundLiteralRegion - Retrieve the region associated with a
1470   ///  given CompoundLiteral.
1471   const CompoundLiteralRegion*
1472   getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1473                            const LocationContext *LC);
1474 
1475   /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1476   ///  parameter 'this'.
1477   const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1478                                         const LocationContext *LC);
1479 
1480   /// Retrieve or create a "symbolic" memory region.
1481   /// If no memory space is specified, `UnknownSpaceRegion` will be used.
1482   const SymbolicRegion *
1483   getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr);
1484 
1485   /// Return a unique symbolic region belonging to heap memory space.
1486   const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1487 
1488   const StringRegion *getStringRegion(const StringLiteral *Str);
1489 
1490   const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1491 
1492   /// getVarRegion - Retrieve or create the memory region associated with
1493   ///  a specified VarDecl and LocationContext.
1494   const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC);
1495 
1496   /// getVarRegion - Retrieve or create the memory region associated with
1497   ///  a specified VarDecl and LocationContext.
1498   const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD,
1499                                                 const MemRegion *superR);
1500 
1501   /// getParamVarRegion - Retrieve or create the memory region
1502   /// associated with a specified CallExpr, Index and LocationContext.
1503   const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr,
1504                                           unsigned Index,
1505                                           const LocationContext *LC);
1506 
1507   /// getElementRegion - Retrieve the memory region associated with the
1508   ///  associated element type, index, and super region.
1509   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1510                                         const SubRegion *superRegion,
1511                                         const ASTContext &Ctx);
1512 
1513   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1514                                                  const SubRegion *superRegion) {
1515     return getElementRegion(ER->getElementType(), ER->getIndex(),
1516                             superRegion, ER->getContext());
1517   }
1518 
1519   /// getFieldRegion - Retrieve or create the memory region associated with
1520   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
1521   ///  memory region (which typically represents the memory representing
1522   ///  a structure or class).
1523   const FieldRegion *getFieldRegion(const FieldDecl *fd,
1524                                     const SubRegion* superRegion);
1525 
1526   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1527                                              const SubRegion *superRegion) {
1528     return getFieldRegion(FR->getDecl(), superRegion);
1529   }
1530 
1531   /// getObjCIvarRegion - Retrieve or create the memory region associated with
1532   ///   a specified Objective-c instance variable.  'superRegion' corresponds
1533   ///   to the containing region (which typically represents the Objective-C
1534   ///   object).
1535   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1536                                           const SubRegion* superRegion);
1537 
1538   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1539                                                     LocationContext const *LC);
1540 
1541   /// Create a CXXLifetimeExtendedObjectRegion for temporaries which are
1542   /// lifetime-extended by local references.
1543   const CXXLifetimeExtendedObjectRegion *
1544   getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD,
1545                                      LocationContext const *LC);
1546 
1547   /// Create a CXXLifetimeExtendedObjectRegion for temporaries which are
1548   /// lifetime-extended by *static* references.
1549   /// This differs from \ref getCXXLifetimeExtendedObjectRegion(Expr const *,
1550   /// ValueDecl const *, LocationContext const *) in the super-region used.
1551   const CXXLifetimeExtendedObjectRegion *
1552   getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD);
1553 
1554   /// Create a CXXBaseObjectRegion with the given base class for region
1555   /// \p Super.
1556   ///
1557   /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1558   const CXXBaseObjectRegion *
1559   getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1560                          bool IsVirtual);
1561 
1562   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1563   /// super region.
1564   const CXXBaseObjectRegion *
1565   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1566                                   const SubRegion *superRegion) {
1567     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1568                                   baseReg->isVirtual());
1569   }
1570 
1571   /// Create a CXXDerivedObjectRegion with the given derived class for region
1572   /// \p Super. This should not be used for casting an existing
1573   /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1574   /// should be removed.
1575   const CXXDerivedObjectRegion *
1576   getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1577                             const SubRegion *Super);
1578 
1579   const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1580   const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1581                                             CanQualType locTy,
1582                                             AnalysisDeclContext *AC);
1583 
1584   /// getBlockDataRegion - Get the memory region associated with an instance
1585   ///  of a block.  Unlike many other MemRegions, the LocationContext*
1586   ///  argument is allowed to be NULL for cases where we have no known
1587   ///  context.
1588   const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1589                                             const LocationContext *lc,
1590                                             unsigned blockCount);
1591 
1592 private:
1593   template <typename RegionTy, typename SuperTy,
1594             typename Arg1Ty>
1595   RegionTy* getSubRegion(const Arg1Ty arg1,
1596                          const SuperTy* superRegion);
1597 
1598   template <typename RegionTy, typename SuperTy,
1599             typename Arg1Ty, typename Arg2Ty>
1600   RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1601                          const SuperTy* superRegion);
1602 
1603   template <typename RegionTy, typename SuperTy,
1604             typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1605   RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1606                          const Arg3Ty arg3,
1607                          const SuperTy* superRegion);
1608 
1609   template <typename REG>
1610   const REG* LazyAllocate(REG*& region);
1611 
1612   template <typename REG, typename ARG>
1613   const REG* LazyAllocate(REG*& region, ARG a);
1614 };
1615 
1616 //===----------------------------------------------------------------------===//
1617 // Out-of-line member definitions.
1618 //===----------------------------------------------------------------------===//
1619 
1620 inline ASTContext &MemRegion::getContext() const {
1621   return getMemRegionManager().getContext();
1622 }
1623 
1624 //===----------------------------------------------------------------------===//
1625 // Means for storing region/symbol handling traits.
1626 //===----------------------------------------------------------------------===//
1627 
1628 /// Information about invalidation for a particular region/symbol.
1629 class RegionAndSymbolInvalidationTraits {
1630   using StorageTypeForKinds = unsigned char;
1631 
1632   llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1633   llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1634 
1635   using const_region_iterator =
1636       llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1637   using const_symbol_iterator =
1638       llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1639 
1640 public:
1641   /// Describes different invalidation traits.
1642   enum InvalidationKinds {
1643     /// Tells that a region's contents is not changed.
1644     TK_PreserveContents = 0x1,
1645 
1646     /// Suppress pointer-escaping of a region.
1647     TK_SuppressEscape = 0x2,
1648 
1649     // Do not invalidate super region.
1650     TK_DoNotInvalidateSuperRegion = 0x4,
1651 
1652     /// When applied to a MemSpaceRegion, indicates the entire memory space
1653     /// should be invalidated.
1654     TK_EntireMemSpace = 0x8
1655 
1656     // Do not forget to extend StorageTypeForKinds if number of traits exceed
1657     // the number of bits StorageTypeForKinds can store.
1658   };
1659 
1660   void setTrait(SymbolRef Sym, InvalidationKinds IK);
1661   void setTrait(const MemRegion *MR, InvalidationKinds IK);
1662   bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1663   bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1664 };
1665 
1666 //===----------------------------------------------------------------------===//
1667 // Pretty-printing regions.
1668 //===----------------------------------------------------------------------===//
1669 inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1670   R->dumpToStream(os);
1671   return os;
1672 }
1673 
1674 } // namespace ento
1675 
1676 } // namespace clang
1677 
1678 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H