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