xref: /freebsd/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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/PointerIntPair.h"
34 #include "llvm/ADT/iterator_range.h"
35 #include "llvm/Support/Allocator.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include <cassert>
39 #include <cstdint>
40 #include <limits>
41 #include <optional>
42 #include <string>
43 #include <utility>
44 
45 namespace clang {
46 
47 class AnalysisDeclContext;
48 class CXXRecordDecl;
49 class Decl;
50 class LocationContext;
51 class StackFrameContext;
52 
53 namespace ento {
54 
55 class CodeTextRegion;
56 class MemRegion;
57 class MemRegionManager;
58 class MemSpaceRegion;
59 class SValBuilder;
60 class SymbolicRegion;
61 class VarRegion;
62 
63 /// Represent a region's offset within the top level base region.
64 class RegionOffset {
65   /// The base region.
66   const MemRegion *R = nullptr;
67 
68   /// The bit offset within the base region. Can be negative.
69   int64_t Offset;
70 
71 public:
72   // We're using a const instead of an enumeration due to the size required;
73   // Visual Studio will only create enumerations of size int, not long long.
74   static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
75 
76   RegionOffset() = default;
RegionOffset(const MemRegion * r,int64_t off)77   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
78 
79   /// It might return null.
getRegion()80   const MemRegion *getRegion() const { return R; }
81 
hasSymbolicOffset()82   bool hasSymbolicOffset() const { return Offset == Symbolic; }
83 
getOffset()84   int64_t getOffset() const {
85     assert(!hasSymbolicOffset());
86     return Offset;
87   }
88 
isValid()89   bool isValid() const { return R; }
90 };
91 
92 //===----------------------------------------------------------------------===//
93 // Base region classes.
94 //===----------------------------------------------------------------------===//
95 
96 /// MemRegion - The root abstract class for all memory regions.
97 class MemRegion : public llvm::FoldingSetNode {
98 public:
99   enum Kind {
100 #define REGION(Id, Parent) Id ## Kind,
101 #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
102 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
103 #undef REGION
104 #undef REGION_RANGE
105   };
106 
107 private:
108   const Kind kind;
109   mutable std::optional<RegionOffset> cachedOffset;
110 
111 protected:
MemRegion(Kind k)112   MemRegion(Kind k) : kind(k) {}
113   virtual ~MemRegion();
114 
115 public:
116   ASTContext &getContext() const;
117 
118   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
119 
120   virtual MemRegionManager &getMemRegionManager() const = 0;
121 
122   LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const;
123 
124   LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const;
125 
126   /// Recursively retrieve the region of the most derived class instance of
127   /// regions of C++ base class instances.
128   LLVM_ATTRIBUTE_RETURNS_NONNULL
129   const MemRegion *getMostDerivedObjectRegion() const;
130 
131   /// Check if the region is a subregion of the given region.
132   /// Each region is a subregion of itself.
133   virtual bool isSubRegionOf(const MemRegion *R) const;
134 
135   LLVM_ATTRIBUTE_RETURNS_NONNULL
136   const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
137 
138   /// If this is a symbolic region, returns the region. Otherwise,
139   /// goes up the base chain looking for the first symbolic base region.
140   /// It might return null.
141   const SymbolicRegion *getSymbolicBase() const;
142 
143   bool hasStackStorage() const;
144 
145   bool hasStackNonParametersStorage() const;
146 
147   bool hasStackParametersStorage() const;
148 
149   /// Compute the offset within the top level memory object.
150   RegionOffset getAsOffset() const;
151 
152   /// Get a string representation of a region for debug use.
153   std::string getString() const;
154 
155   virtual void dumpToStream(raw_ostream &os) const;
156 
157   void dump() const;
158 
159   /// Returns true if this region can be printed in a user-friendly way.
160   virtual bool canPrintPretty() const;
161 
162   /// Print the region for use in diagnostics.
163   virtual void printPretty(raw_ostream &os) const;
164 
165   /// Returns true if this region's textual representation can be used
166   /// as part of a larger expression.
167   virtual bool canPrintPrettyAsExpr() const;
168 
169   /// Print the region as expression.
170   ///
171   /// When this region represents a subexpression, the method is for printing
172   /// an expression containing it.
173   virtual void printPrettyAsExpr(raw_ostream &os) const;
174 
getKind()175   Kind getKind() const { return kind; }
176 
177   StringRef getKindStr() const;
178 
179   template<typename RegionTy> const RegionTy* getAs() const;
180   template <typename RegionTy>
181   LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const;
182 
isBoundable()183   virtual bool isBoundable() const { return false; }
184 
185   /// Get descriptive name for memory region. The name is obtained from
186   /// the variable/field declaration retrieved from the memory region.
187   /// Regions that point to an element of an array are returned as: "arr[0]".
188   /// Regions that point to a struct are returned as: "st.var".
189   //
190   /// \param UseQuotes Set if the name should be quoted.
191   ///
192   /// \returns variable name for memory region
193   std::string getDescriptiveName(bool UseQuotes = true) const;
194 
195   /// Retrieve source range from memory region. The range retrieval
196   /// is based on the decl obtained from the memory region.
197   /// For a VarRegion the range of the base region is returned.
198   /// For a FieldRegion the range of the field is returned.
199   /// If no declaration is found, an empty source range is returned.
200   /// The client is responsible for checking if the returned range is valid.
201   ///
202   /// \returns source range for declaration retrieved from memory region
203   SourceRange sourceRange() const;
204 };
205 
206 /// MemSpaceRegion - A memory region that represents a "memory space";
207 ///  for example, the set of global variables, the stack frame, etc.
208 class MemSpaceRegion : public MemRegion {
209 protected:
210   MemRegionManager &Mgr;
211 
MemSpaceRegion(MemRegionManager & mgr,Kind k)212   MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
213     assert(classof(this));
214   }
215 
getMemRegionManager()216   MemRegionManager &getMemRegionManager() const override { return Mgr; }
217 
218 public:
isBoundable()219   bool isBoundable() const override { return false; }
220 
221   void Profile(llvm::FoldingSetNodeID &ID) const override;
222 
classof(const MemRegion * R)223   static bool classof(const MemRegion *R) {
224     Kind k = R->getKind();
225     return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
226   }
227 };
228 
229 /// CodeSpaceRegion - The memory space that holds the executable code of
230 /// functions and blocks.
231 class CodeSpaceRegion : public MemSpaceRegion {
232   friend class MemRegionManager;
233 
CodeSpaceRegion(MemRegionManager & mgr)234   CodeSpaceRegion(MemRegionManager &mgr)
235       : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
236 
237 public:
238   void dumpToStream(raw_ostream &os) const override;
239 
classof(const MemRegion * R)240   static bool classof(const MemRegion *R) {
241     return R->getKind() == CodeSpaceRegionKind;
242   }
243 };
244 
245 class GlobalsSpaceRegion : public MemSpaceRegion {
246   virtual void anchor();
247 
248 protected:
GlobalsSpaceRegion(MemRegionManager & mgr,Kind k)249   GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
250     assert(classof(this));
251   }
252 
253 public:
classof(const MemRegion * R)254   static bool classof(const MemRegion *R) {
255     Kind k = R->getKind();
256     return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
257   }
258 };
259 
260 /// The region of the static variables within the current CodeTextRegion
261 /// scope.
262 ///
263 /// Currently, only the static locals are placed there, so we know that these
264 /// variables do not get invalidated by calls to other functions.
265 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
266   friend class MemRegionManager;
267 
268   const CodeTextRegion *CR;
269 
StaticGlobalSpaceRegion(MemRegionManager & mgr,const CodeTextRegion * cr)270   StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr)
271       : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
272     assert(cr);
273   }
274 
275 public:
276   void Profile(llvm::FoldingSetNodeID &ID) const override;
277 
278   void dumpToStream(raw_ostream &os) const override;
279 
280   LLVM_ATTRIBUTE_RETURNS_NONNULL
getCodeRegion()281   const CodeTextRegion *getCodeRegion() const { return CR; }
282 
classof(const MemRegion * R)283   static bool classof(const MemRegion *R) {
284     return R->getKind() == StaticGlobalSpaceRegionKind;
285   }
286 };
287 
288 /// The region for all the non-static global variables.
289 ///
290 /// This class is further split into subclasses for efficient implementation of
291 /// invalidating a set of related global values as is done in
292 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
293 /// globals, we invalidate the whole parent region).
294 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
295   void anchor() override;
296 
297 protected:
NonStaticGlobalSpaceRegion(MemRegionManager & mgr,Kind k)298   NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
299       : GlobalsSpaceRegion(mgr, k) {
300     assert(classof(this));
301   }
302 
303 public:
classof(const MemRegion * R)304   static bool classof(const MemRegion *R) {
305     Kind k = R->getKind();
306     return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
307            k <= END_NON_STATIC_GLOBAL_MEMSPACES;
308   }
309 };
310 
311 /// The region containing globals which are defined in system/external
312 /// headers and are considered modifiable by system calls (ex: errno).
313 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
314   friend class MemRegionManager;
315 
GlobalSystemSpaceRegion(MemRegionManager & mgr)316   GlobalSystemSpaceRegion(MemRegionManager &mgr)
317       : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
318 
319 public:
320   void dumpToStream(raw_ostream &os) const override;
321 
classof(const MemRegion * R)322   static bool classof(const MemRegion *R) {
323     return R->getKind() == GlobalSystemSpaceRegionKind;
324   }
325 };
326 
327 /// The region containing globals which are considered not to be modified
328 /// or point to data which could be modified as a result of a function call
329 /// (system or internal). Ex: Const global scalars would be modeled as part of
330 /// this region. This region also includes most system globals since they have
331 /// low chance of being modified.
332 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
333   friend class MemRegionManager;
334 
GlobalImmutableSpaceRegion(MemRegionManager & mgr)335   GlobalImmutableSpaceRegion(MemRegionManager &mgr)
336       : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
337 
338 public:
339   void dumpToStream(raw_ostream &os) const override;
340 
classof(const MemRegion * R)341   static bool classof(const MemRegion *R) {
342     return R->getKind() == GlobalImmutableSpaceRegionKind;
343   }
344 };
345 
346 /// The region containing globals which can be modified by calls to
347 /// "internally" defined functions - (for now just) functions other then system
348 /// calls.
349 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
350   friend class MemRegionManager;
351 
GlobalInternalSpaceRegion(MemRegionManager & mgr)352   GlobalInternalSpaceRegion(MemRegionManager &mgr)
353       : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
354 
355 public:
356   void dumpToStream(raw_ostream &os) const override;
357 
classof(const MemRegion * R)358   static bool classof(const MemRegion *R) {
359     return R->getKind() == GlobalInternalSpaceRegionKind;
360   }
361 };
362 
363 class HeapSpaceRegion : public MemSpaceRegion {
364   friend class MemRegionManager;
365 
HeapSpaceRegion(MemRegionManager & mgr)366   HeapSpaceRegion(MemRegionManager &mgr)
367       : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
368 
369 public:
370   void dumpToStream(raw_ostream &os) const override;
371 
classof(const MemRegion * R)372   static bool classof(const MemRegion *R) {
373     return R->getKind() == HeapSpaceRegionKind;
374   }
375 };
376 
377 class UnknownSpaceRegion : public MemSpaceRegion {
378   friend class MemRegionManager;
379 
UnknownSpaceRegion(MemRegionManager & mgr)380   UnknownSpaceRegion(MemRegionManager &mgr)
381       : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
382 
383 public:
384   void dumpToStream(raw_ostream &os) const override;
385 
classof(const MemRegion * R)386   static bool classof(const MemRegion *R) {
387     return R->getKind() == UnknownSpaceRegionKind;
388   }
389 };
390 
391 class StackSpaceRegion : public MemSpaceRegion {
392   virtual void anchor();
393 
394   const StackFrameContext *SFC;
395 
396 protected:
StackSpaceRegion(MemRegionManager & mgr,Kind k,const StackFrameContext * sfc)397   StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
398       : MemSpaceRegion(mgr, k), SFC(sfc) {
399     assert(classof(this));
400     assert(sfc);
401   }
402 
403 public:
404   LLVM_ATTRIBUTE_RETURNS_NONNULL
getStackFrame()405   const StackFrameContext *getStackFrame() const { return SFC; }
406 
407   void Profile(llvm::FoldingSetNodeID &ID) const override;
408 
classof(const MemRegion * R)409   static bool classof(const MemRegion *R) {
410     Kind k = R->getKind();
411     return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
412   }
413 };
414 
415 class StackLocalsSpaceRegion : public StackSpaceRegion {
416   friend class MemRegionManager;
417 
StackLocalsSpaceRegion(MemRegionManager & mgr,const StackFrameContext * sfc)418   StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
419       : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
420 
421 public:
422   void dumpToStream(raw_ostream &os) const override;
423 
classof(const MemRegion * R)424   static bool classof(const MemRegion *R) {
425     return R->getKind() == StackLocalsSpaceRegionKind;
426   }
427 };
428 
429 class StackArgumentsSpaceRegion : public StackSpaceRegion {
430 private:
431   friend class MemRegionManager;
432 
StackArgumentsSpaceRegion(MemRegionManager & mgr,const StackFrameContext * sfc)433   StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
434       : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
435 
436 public:
437   void dumpToStream(raw_ostream &os) const override;
438 
classof(const MemRegion * R)439   static bool classof(const MemRegion *R) {
440     return R->getKind() == StackArgumentsSpaceRegionKind;
441   }
442 };
443 
444 /// SubRegion - A region that subsets another larger region.  Most regions
445 ///  are subclasses of SubRegion.
446 class SubRegion : public MemRegion {
447   virtual void anchor();
448 
449 protected:
450   const MemRegion* superRegion;
451 
SubRegion(const MemRegion * sReg,Kind k)452   SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
453     assert(classof(this));
454     assert(sReg);
455   }
456 
457 public:
458   LLVM_ATTRIBUTE_RETURNS_NONNULL
getSuperRegion()459   const MemRegion* getSuperRegion() const {
460     return superRegion;
461   }
462 
463   MemRegionManager &getMemRegionManager() const override;
464 
465   bool isSubRegionOf(const MemRegion* R) const override;
466 
classof(const MemRegion * R)467   static bool classof(const MemRegion* R) {
468     return R->getKind() > END_MEMSPACES;
469   }
470 };
471 
472 //===----------------------------------------------------------------------===//
473 // MemRegion subclasses.
474 //===----------------------------------------------------------------------===//
475 
476 /// AllocaRegion - A region that represents an untyped blob of bytes created
477 ///  by a call to 'alloca'.
478 class AllocaRegion : public SubRegion {
479   friend class MemRegionManager;
480 
481   // Block counter. Used to distinguish different pieces of memory allocated by
482   // alloca at the same call site.
483   unsigned Cnt;
484 
485   const Expr *Ex;
486 
AllocaRegion(const Expr * ex,unsigned cnt,const MemSpaceRegion * superRegion)487   AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
488       : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
489     assert(Ex);
490   }
491 
492   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
493                             unsigned Cnt, const MemRegion *superRegion);
494 
495 public:
496   LLVM_ATTRIBUTE_RETURNS_NONNULL
getExpr()497   const Expr *getExpr() const { return Ex; }
498 
isBoundable()499   bool isBoundable() const override { return true; }
500 
501   void Profile(llvm::FoldingSetNodeID& ID) const override;
502 
503   void dumpToStream(raw_ostream &os) const override;
504 
classof(const MemRegion * R)505   static bool classof(const MemRegion* R) {
506     return R->getKind() == AllocaRegionKind;
507   }
508 };
509 
510 /// TypedRegion - An abstract class representing regions that are typed.
511 class TypedRegion : public SubRegion {
512   void anchor() override;
513 
514 protected:
TypedRegion(const MemRegion * sReg,Kind k)515   TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
516     assert(classof(this));
517   }
518 
519 public:
520   virtual QualType getLocationType() const = 0;
521 
getDesugaredLocationType(ASTContext & Context)522   QualType getDesugaredLocationType(ASTContext &Context) const {
523     return getLocationType().getDesugaredType(Context);
524   }
525 
isBoundable()526   bool isBoundable() const override { return true; }
527 
classof(const MemRegion * R)528   static bool classof(const MemRegion* R) {
529     unsigned k = R->getKind();
530     return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
531   }
532 };
533 
534 /// TypedValueRegion - An abstract class representing regions having a typed value.
535 class TypedValueRegion : public TypedRegion {
536   void anchor() override;
537 
538 protected:
TypedValueRegion(const MemRegion * sReg,Kind k)539   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
540     assert(classof(this));
541   }
542 
543 public:
544   virtual QualType getValueType() const = 0;
545 
getLocationType()546   QualType getLocationType() const override {
547     // FIXME: We can possibly optimize this later to cache this value.
548     QualType T = getValueType();
549     ASTContext &ctx = getContext();
550     if (T->getAs<ObjCObjectType>())
551       return ctx.getObjCObjectPointerType(T);
552     return ctx.getPointerType(getValueType());
553   }
554 
getDesugaredValueType(ASTContext & Context)555   QualType getDesugaredValueType(ASTContext &Context) const {
556     QualType T = getValueType();
557     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
558   }
559 
classof(const MemRegion * R)560   static bool classof(const MemRegion* R) {
561     unsigned k = R->getKind();
562     return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
563   }
564 };
565 
566 class CodeTextRegion : public TypedRegion {
567   void anchor() override;
568 
569 protected:
CodeTextRegion(const MemSpaceRegion * sreg,Kind k)570   CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
571     assert(classof(this));
572   }
573 
574 public:
isBoundable()575   bool isBoundable() const override { return false; }
576 
classof(const MemRegion * R)577   static bool classof(const MemRegion* R) {
578     Kind k = R->getKind();
579     return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS;
580   }
581 };
582 
583 /// FunctionCodeRegion - A region that represents code texts of function.
584 class FunctionCodeRegion : public CodeTextRegion {
585   friend class MemRegionManager;
586 
587   const NamedDecl *FD;
588 
FunctionCodeRegion(const NamedDecl * fd,const CodeSpaceRegion * sreg)589   FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
590       : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
591     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
592   }
593 
594   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
595                             const MemRegion*);
596 
597 public:
getLocationType()598   QualType getLocationType() const override {
599     const ASTContext &Ctx = getContext();
600     if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
601       return Ctx.getPointerType(D->getType());
602     }
603 
604     assert(isa<ObjCMethodDecl>(FD));
605     assert(false && "Getting the type of ObjCMethod is not supported yet");
606 
607     // TODO: We might want to return a different type here (ex: id (*ty)(...))
608     //       depending on how it is used.
609     return {};
610   }
611 
getDecl()612   const NamedDecl *getDecl() const {
613     return FD;
614   }
615 
616   void dumpToStream(raw_ostream &os) const override;
617 
618   void Profile(llvm::FoldingSetNodeID& ID) const override;
619 
classof(const MemRegion * R)620   static bool classof(const MemRegion* R) {
621     return R->getKind() == FunctionCodeRegionKind;
622   }
623 };
624 
625 /// BlockCodeRegion - A region that represents code texts of blocks (closures).
626 ///  Blocks are represented with two kinds of regions.  BlockCodeRegions
627 ///  represent the "code", while BlockDataRegions represent instances of blocks,
628 ///  which correspond to "code+data".  The distinction is important, because
629 ///  like a closure a block captures the values of externally referenced
630 ///  variables.
631 class BlockCodeRegion : public CodeTextRegion {
632   friend class MemRegionManager;
633 
634   const BlockDecl *BD;
635   AnalysisDeclContext *AC;
636   CanQualType locTy;
637 
BlockCodeRegion(const BlockDecl * bd,CanQualType lTy,AnalysisDeclContext * ac,const CodeSpaceRegion * sreg)638   BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
639                   AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
640       : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
641     assert(bd);
642     assert(ac);
643     assert(lTy->getTypePtr()->isBlockPointerType());
644   }
645 
646   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
647                             CanQualType, const AnalysisDeclContext*,
648                             const MemRegion*);
649 
650 public:
getLocationType()651   QualType getLocationType() const override {
652     return locTy;
653   }
654 
655   LLVM_ATTRIBUTE_RETURNS_NONNULL
getDecl()656   const BlockDecl *getDecl() const {
657     return BD;
658   }
659 
660   LLVM_ATTRIBUTE_RETURNS_NONNULL
getAnalysisDeclContext()661   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
662 
663   void dumpToStream(raw_ostream &os) const override;
664 
665   void Profile(llvm::FoldingSetNodeID& ID) const override;
666 
classof(const MemRegion * R)667   static bool classof(const MemRegion* R) {
668     return R->getKind() == BlockCodeRegionKind;
669   }
670 };
671 
672 /// BlockDataRegion - A region that represents a block instance.
673 ///  Blocks are represented with two kinds of regions.  BlockCodeRegions
674 ///  represent the "code", while BlockDataRegions represent instances of blocks,
675 ///  which correspond to "code+data".  The distinction is important, because
676 ///  like a closure a block captures the values of externally referenced
677 ///  variables.
678 class BlockDataRegion : public TypedRegion {
679   friend class MemRegionManager;
680 
681   const BlockCodeRegion *BC;
682   const LocationContext *LC; // Can be null
683   unsigned BlockCount;
684   void *ReferencedVars = nullptr;
685   void *OriginalVars = nullptr;
686 
BlockDataRegion(const BlockCodeRegion * bc,const LocationContext * lc,unsigned count,const MemSpaceRegion * sreg)687   BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
688                   unsigned count, const MemSpaceRegion *sreg)
689       : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
690         BlockCount(count) {
691     assert(bc);
692     assert(bc->getDecl());
693     assert(lc);
694     assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
695            isa<StackLocalsSpaceRegion>(sreg) ||
696            isa<UnknownSpaceRegion>(sreg));
697   }
698 
699   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
700                             const LocationContext *, unsigned,
701                             const MemRegion *);
702 
703 public:
704   LLVM_ATTRIBUTE_RETURNS_NONNULL
getCodeRegion()705   const BlockCodeRegion *getCodeRegion() const { return BC; }
706 
707   LLVM_ATTRIBUTE_RETURNS_NONNULL
getDecl()708   const BlockDecl *getDecl() const { return BC->getDecl(); }
709 
getLocationType()710   QualType getLocationType() const override { return BC->getLocationType(); }
711 
712   class referenced_vars_iterator {
713     const MemRegion * const *R;
714     const MemRegion * const *OriginalR;
715 
716   public:
referenced_vars_iterator(const MemRegion * const * r,const MemRegion * const * originalR)717     explicit referenced_vars_iterator(const MemRegion * const *r,
718                                       const MemRegion * const *originalR)
719         : R(r), OriginalR(originalR) {}
720 
721     LLVM_ATTRIBUTE_RETURNS_NONNULL
getCapturedRegion()722     const VarRegion *getCapturedRegion() const {
723       return cast<VarRegion>(*R);
724     }
725 
726     LLVM_ATTRIBUTE_RETURNS_NONNULL
getOriginalRegion()727     const VarRegion *getOriginalRegion() const {
728       return cast<VarRegion>(*OriginalR);
729     }
730 
731     bool operator==(const referenced_vars_iterator &I) const {
732       assert((R == nullptr) == (I.R == nullptr));
733       return I.R == R;
734     }
735 
736     bool operator!=(const referenced_vars_iterator &I) const {
737       assert((R == nullptr) == (I.R == nullptr));
738       return I.R != R;
739     }
740 
741     referenced_vars_iterator &operator++() {
742       ++R;
743       ++OriginalR;
744       return *this;
745     }
746 
747     // This isn't really a conventional iterator.
748     // We just implement the deref as a no-op for now to make range-based for
749     // loops work.
750     const referenced_vars_iterator &operator*() const { return *this; }
751   };
752 
753   /// Return the original region for a captured region, if
754   /// one exists. It might return null.
755   const VarRegion *getOriginalRegion(const VarRegion *VR) const;
756 
757   referenced_vars_iterator referenced_vars_begin() const;
758   referenced_vars_iterator referenced_vars_end() const;
759   llvm::iterator_range<referenced_vars_iterator> referenced_vars() const;
760 
761   void dumpToStream(raw_ostream &os) const override;
762 
763   void Profile(llvm::FoldingSetNodeID& ID) const override;
764 
classof(const MemRegion * R)765   static bool classof(const MemRegion* R) {
766     return R->getKind() == BlockDataRegionKind;
767   }
768 
769 private:
770   void LazyInitializeReferencedVars();
771   std::pair<const VarRegion *, const VarRegion *>
772   getCaptureRegions(const VarDecl *VD);
773 };
774 
775 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
776 ///  classes, SymbolicRegion represents a region that serves as an alias for
777 ///  either a real region, a NULL pointer, etc.  It essentially is used to
778 ///  map the concept of symbolic values into the domain of regions.  Symbolic
779 ///  regions do not need to be typed.
780 class SymbolicRegion : public SubRegion {
781   friend class MemRegionManager;
782 
783   const SymbolRef sym;
784 
SymbolicRegion(const SymbolRef s,const MemSpaceRegion * sreg)785   SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
786       : SubRegion(sreg, SymbolicRegionKind), sym(s) {
787     // Because pointer arithmetic is represented by ElementRegion layers,
788     // the base symbol here should not contain any arithmetic.
789     assert(isa_and_nonnull<SymbolData>(s));
790     assert(s->getType()->isAnyPointerType() ||
791            s->getType()->isReferenceType() ||
792            s->getType()->isBlockPointerType());
793     assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) ||
794            isa<GlobalSystemSpaceRegion>(sreg));
795   }
796 
797 public:
798   /// It might return null.
getSymbol()799   SymbolRef getSymbol() const { return sym; }
800 
801   /// Gets the type of the wrapped symbol.
802   /// This type might not be accurate at all times - it's just our best guess.
803   /// Consider these cases:
804   ///   void foo(void *data, char *str, base *obj) {...}
805   /// The type of the pointee of `data` is of course not `void`, yet that's our
806   /// best guess. `str` might point to any object and `obj` might point to some
807   /// derived instance. `TypedRegions` other hand are representing the cases
808   /// when we actually know their types.
getPointeeStaticType()809   QualType getPointeeStaticType() const {
810     return sym->getType()->getPointeeType();
811   }
812 
isBoundable()813   bool isBoundable() const override { return true; }
814 
815   void Profile(llvm::FoldingSetNodeID& ID) const override;
816 
817   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
818                             SymbolRef sym,
819                             const MemRegion* superRegion);
820 
821   void dumpToStream(raw_ostream &os) const override;
822 
classof(const MemRegion * R)823   static bool classof(const MemRegion* R) {
824     return R->getKind() == SymbolicRegionKind;
825   }
826 };
827 
828 /// StringRegion - Region associated with a StringLiteral.
829 class StringRegion : public TypedValueRegion {
830   friend class MemRegionManager;
831 
832   const StringLiteral *Str;
833 
StringRegion(const StringLiteral * str,const GlobalInternalSpaceRegion * sreg)834   StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
835       : TypedValueRegion(sreg, StringRegionKind), Str(str) {
836     assert(str);
837   }
838 
839   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
840                             const StringLiteral *Str,
841                             const MemRegion *superRegion);
842 
843 public:
844   LLVM_ATTRIBUTE_RETURNS_NONNULL
getStringLiteral()845   const StringLiteral *getStringLiteral() const { return Str; }
846 
getValueType()847   QualType getValueType() const override { return Str->getType(); }
848 
isBoundable()849   bool isBoundable() const override { return false; }
850 
Profile(llvm::FoldingSetNodeID & ID)851   void Profile(llvm::FoldingSetNodeID& ID) const override {
852     ProfileRegion(ID, Str, superRegion);
853   }
854 
855   void dumpToStream(raw_ostream &os) const override;
856 
classof(const MemRegion * R)857   static bool classof(const MemRegion* R) {
858     return R->getKind() == StringRegionKind;
859   }
860 };
861 
862 /// The region associated with an ObjCStringLiteral.
863 class ObjCStringRegion : public TypedValueRegion {
864   friend class MemRegionManager;
865 
866   const ObjCStringLiteral *Str;
867 
ObjCStringRegion(const ObjCStringLiteral * str,const GlobalInternalSpaceRegion * sreg)868   ObjCStringRegion(const ObjCStringLiteral *str,
869                    const GlobalInternalSpaceRegion *sreg)
870       : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
871     assert(str);
872   }
873 
874   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
875                             const ObjCStringLiteral *Str,
876                             const MemRegion *superRegion);
877 
878 public:
879   LLVM_ATTRIBUTE_RETURNS_NONNULL
getObjCStringLiteral()880   const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
881 
getValueType()882   QualType getValueType() const override { return Str->getType(); }
883 
isBoundable()884   bool isBoundable() const override { return false; }
885 
Profile(llvm::FoldingSetNodeID & ID)886   void Profile(llvm::FoldingSetNodeID& ID) const override {
887     ProfileRegion(ID, Str, superRegion);
888   }
889 
890   void dumpToStream(raw_ostream &os) const override;
891 
classof(const MemRegion * R)892   static bool classof(const MemRegion* R) {
893     return R->getKind() == ObjCStringRegionKind;
894   }
895 };
896 
897 /// CompoundLiteralRegion - A memory region representing a compound literal.
898 ///   Compound literals are essentially temporaries that are stack allocated
899 ///   or in the global constant pool.
900 class CompoundLiteralRegion : public TypedValueRegion {
901   friend class MemRegionManager;
902 
903   const CompoundLiteralExpr *CL;
904 
CompoundLiteralRegion(const CompoundLiteralExpr * cl,const MemSpaceRegion * sReg)905   CompoundLiteralRegion(const CompoundLiteralExpr *cl,
906                         const MemSpaceRegion *sReg)
907       : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
908     assert(cl);
909     assert(isa<GlobalInternalSpaceRegion>(sReg) ||
910            isa<StackLocalsSpaceRegion>(sReg));
911   }
912 
913   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
914                             const CompoundLiteralExpr *CL,
915                             const MemRegion* superRegion);
916 
917 public:
getValueType()918   QualType getValueType() const override { return CL->getType(); }
919 
isBoundable()920   bool isBoundable() const override { return !CL->isFileScope(); }
921 
922   void Profile(llvm::FoldingSetNodeID& ID) const override;
923 
924   void dumpToStream(raw_ostream &os) const override;
925 
926   LLVM_ATTRIBUTE_RETURNS_NONNULL
getLiteralExpr()927   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
928 
classof(const MemRegion * R)929   static bool classof(const MemRegion* R) {
930     return R->getKind() == CompoundLiteralRegionKind;
931   }
932 };
933 
934 class DeclRegion : public TypedValueRegion {
935 protected:
DeclRegion(const MemRegion * sReg,Kind k)936   DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
937     assert(classof(this));
938   }
939 
940 public:
941   // TODO what does this return?
942   virtual const ValueDecl *getDecl() const = 0;
943 
classof(const MemRegion * R)944   static bool classof(const MemRegion* R) {
945     unsigned k = R->getKind();
946     return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
947   }
948 };
949 
950 class VarRegion : public DeclRegion {
951   friend class MemRegionManager;
952 
953 protected:
954   // Constructors and protected methods.
VarRegion(const MemRegion * sReg,Kind k)955   VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) {
956     // VarRegion appears in unknown space when it's a block variable as seen
957     // from a block using it, when this block is analyzed at top-level.
958     // Other block variables appear within block data regions,
959     // which, unlike everything else on this list, are not memory spaces.
960     assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
961            isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
962   }
963 
964 public:
965   // TODO what does this return?
966   const VarDecl *getDecl() const override = 0;
967 
968   /// It might return null.
969   const StackFrameContext *getStackFrame() const;
970 
getValueType()971   QualType getValueType() const override {
972     // FIXME: We can cache this if needed.
973     return getDecl()->getType();
974   }
975 
classof(const MemRegion * R)976   static bool classof(const MemRegion *R) {
977     unsigned k = R->getKind();
978     return k >= BEGIN_VAR_REGIONS && k <= END_VAR_REGIONS;
979   }
980 };
981 
982 class NonParamVarRegion : public VarRegion {
983   friend class MemRegionManager;
984 
985   const VarDecl *VD;
986 
987   // Constructors and private methods.
NonParamVarRegion(const VarDecl * vd,const MemRegion * sReg)988   NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg)
989       : VarRegion(sReg, NonParamVarRegionKind), VD(vd) {
990     // VarRegion appears in unknown space when it's a block variable as seen
991     // from a block using it, when this block is analyzed at top-level.
992     // Other block variables appear within block data regions,
993     // which, unlike everything else on this list, are not memory spaces.
994     assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
995            isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
996     assert(vd);
997   }
998 
999   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
getDecl()1006   const VarDecl *getDecl() const override { return VD; }
1007 
getValueType()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 
classof(const MemRegion * R)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 
ParamVarRegion(const Expr * OE,unsigned Idx,const MemRegion * SReg)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
getOriginExpr()1051   const Expr *getOriginExpr() const { return OriginExpr; }
getIndex()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 
classof(const MemRegion * R)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 
CXXThisRegion(const PointerType * thisPointerTy,const StackArgumentsSpaceRegion * sReg)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 
getValueType()1092   QualType getValueType() const override {
1093     return QualType(ThisPointerTy, 0);
1094   }
1095 
1096   void dumpToStream(raw_ostream &os) const override;
1097 
classof(const MemRegion * R)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 
FieldRegion(const FieldDecl * fd,const SubRegion * sReg)1111   FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
1112       : DeclRegion(sReg, FieldRegionKind), FD(fd) {
1113     assert(FD);
1114   }
1115 
ProfileRegion(llvm::FoldingSetNodeID & ID,const FieldDecl * FD,const MemRegion * superRegion)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
getDecl()1125   const FieldDecl *getDecl() const override { return FD; }
1126 
1127   void Profile(llvm::FoldingSetNodeID &ID) const override;
1128 
getValueType()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 
classof(const MemRegion * R)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 
classof(const MemRegion * R)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())
Region(reg)1185       : Region(reg), Offset(offset) {}
1186 
1187 public:
1188   // FIXME: Eventually support symbolic offsets.
getOffset()1189   CharUnits getOffset() const { return Offset; }
1190 
1191   // It might return null.
getRegion()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 
ElementRegion(QualType elementType,NonLoc Idx,const SubRegion * sReg)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:
getIndex()1219   NonLoc getIndex() const { return Index; }
1220 
getValueType()1221   QualType getValueType() const override { return ElementType; }
1222 
getElementType()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 
classof(const MemRegion * R)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 
CXXTempObjectRegion(Expr const * E,MemSpaceRegion const * sReg)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
getExpr()1254   const Expr *getExpr() const { return Ex; }
1255 
1256   LLVM_ATTRIBUTE_RETURNS_NONNULL
1257   const StackFrameContext *getStackFrame() const;
1258 
getValueType()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 
classof(const MemRegion * R)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 
CXXLifetimeExtendedObjectRegion(Expr const * E,ValueDecl const * D,MemSpaceRegion const * sReg)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
getExpr()1292   const Expr *getExpr() const { return Ex; }
1293   LLVM_ATTRIBUTE_RETURNS_NONNULL
getExtendingDecl()1294   const ValueDecl *getExtendingDecl() const { return ExD; }
1295   /// It might return null.
1296   const StackFrameContext *getStackFrame() const;
1297 
getValueType()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 
classof(const MemRegion * R)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 
CXXBaseObjectRegion(const CXXRecordDecl * RD,bool IsVirtual,const SubRegion * SReg)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
getDecl()1327   const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
isVirtual()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 
classof(const MemRegion * region)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 
CXXDerivedObjectRegion(const CXXRecordDecl * DerivedD,const SubRegion * SReg)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
getDecl()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 
classof(const MemRegion * region)1382   static bool classof(const MemRegion *region) {
1383     return region->getKind() == CXXDerivedObjectRegionKind;
1384   }
1385 };
1386 
1387 template<typename RegionTy>
getAs()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>
castAs()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:
MemRegionManager(ASTContext & c,llvm::BumpPtrAllocator & a)1426   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1427   ~MemRegionManager();
1428 
getContext()1429   ASTContext &getContext() { return Ctx; }
getContext()1430   const ASTContext &getContext() const { return Ctx; }
1431 
getAllocator()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 
getElementRegionWithSuper(const ElementRegion * ER,const SubRegion * superRegion)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 
getFieldRegionWithSuper(const FieldRegion * FR,const SubRegion * superRegion)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 *
getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion * baseReg,const SubRegion * superRegion)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 
getContext()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
1679