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