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
43namespace clang {
44
45class AnalysisDeclContext;
46class CXXRecordDecl;
47class Decl;
48class LocationContext;
49class StackFrameContext;
50
51namespace ento {
52
53class CodeTextRegion;
54class MemRegion;
55class MemRegionManager;
56class MemSpaceRegion;
57class SValBuilder;
58class SymbolicRegion;
59class VarRegion;
60
61/// Represent a region's offset within the top level base region.
62class 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
69public:
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.
95class MemRegion : public llvm::FoldingSetNode {
96public:
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
103private:
104  const Kind kind;
105  mutable std::optional<RegionOffset> cachedOffset;
106
107protected:
108  MemRegion(Kind k) : kind(k) {}
109  virtual ~MemRegion();
110
111public:
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.
204class MemSpaceRegion : public MemRegion {
205protected:
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
214public:
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.
227class CodeSpaceRegion : public MemSpaceRegion {
228  friend class MemRegionManager;
229
230  CodeSpaceRegion(MemRegionManager &mgr)
231      : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
232
233public:
234  void dumpToStream(raw_ostream &os) const override;
235
236  static bool classof(const MemRegion *R) {
237    return R->getKind() == CodeSpaceRegionKind;
238  }
239};
240
241class GlobalsSpaceRegion : public MemSpaceRegion {
242  virtual void anchor();
243
244protected:
245  GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
246    assert(classof(this));
247  }
248
249public:
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.
261class 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
271public:
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).
290class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
291  void anchor() override;
292
293protected:
294  NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
295      : GlobalsSpaceRegion(mgr, k) {
296    assert(classof(this));
297  }
298
299public:
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).
309class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
310  friend class MemRegionManager;
311
312  GlobalSystemSpaceRegion(MemRegionManager &mgr)
313      : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
314
315public:
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.
328class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
329  friend class MemRegionManager;
330
331  GlobalImmutableSpaceRegion(MemRegionManager &mgr)
332      : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
333
334public:
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.
345class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
346  friend class MemRegionManager;
347
348  GlobalInternalSpaceRegion(MemRegionManager &mgr)
349      : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
350
351public:
352  void dumpToStream(raw_ostream &os) const override;
353
354  static bool classof(const MemRegion *R) {
355    return R->getKind() == GlobalInternalSpaceRegionKind;
356  }
357};
358
359class HeapSpaceRegion : public MemSpaceRegion {
360  friend class MemRegionManager;
361
362  HeapSpaceRegion(MemRegionManager &mgr)
363      : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
364
365public:
366  void dumpToStream(raw_ostream &os) const override;
367
368  static bool classof(const MemRegion *R) {
369    return R->getKind() == HeapSpaceRegionKind;
370  }
371};
372
373class UnknownSpaceRegion : public MemSpaceRegion {
374  friend class MemRegionManager;
375
376  UnknownSpaceRegion(MemRegionManager &mgr)
377      : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
378
379public:
380  void dumpToStream(raw_ostream &os) const override;
381
382  static bool classof(const MemRegion *R) {
383    return R->getKind() == UnknownSpaceRegionKind;
384  }
385};
386
387class StackSpaceRegion : public MemSpaceRegion {
388  virtual void anchor();
389
390  const StackFrameContext *SFC;
391
392protected:
393  StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
394      : MemSpaceRegion(mgr, k), SFC(sfc) {
395    assert(classof(this));
396    assert(sfc);
397  }
398
399public:
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
411class StackLocalsSpaceRegion : public StackSpaceRegion {
412  friend class MemRegionManager;
413
414  StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
415      : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
416
417public:
418  void dumpToStream(raw_ostream &os) const override;
419
420  static bool classof(const MemRegion *R) {
421    return R->getKind() == StackLocalsSpaceRegionKind;
422  }
423};
424
425class StackArgumentsSpaceRegion : public StackSpaceRegion {
426private:
427  friend class MemRegionManager;
428
429  StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
430      : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
431
432public:
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.
442class SubRegion : public MemRegion {
443  virtual void anchor();
444
445protected:
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
453public:
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'.
474class 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
491public:
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.
507class TypedRegion : public SubRegion {
508  void anchor() override;
509
510protected:
511  TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
512    assert(classof(this));
513  }
514
515public:
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.
531class TypedValueRegion : public TypedRegion {
532  void anchor() override;
533
534protected:
535  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
536    assert(classof(this));
537  }
538
539public:
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
562class CodeTextRegion : public TypedRegion {
563  void anchor() override;
564
565protected:
566  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
567    assert(classof(this));
568  }
569
570public:
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.
580class 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
593public:
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.
627class 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
646public:
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.
674class 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
699public:
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
759private:
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.
770class 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
787public:
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.
819class 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
833public:
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.
853class 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
868public:
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.
890class 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
907public:
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
924class DeclRegion : public TypedValueRegion {
925protected:
926  DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
927    assert(classof(this));
928  }
929
930public:
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
940class VarRegion : public DeclRegion {
941  friend class MemRegionManager;
942
943protected:
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
954public:
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
972class 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
992public:
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.
1024class 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
1039public:
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.
1064class 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
1079public:
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
1092private:
1093  const PointerType *ThisPointerTy;
1094};
1095
1096class 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
1113public:
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
1136class 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
1146public:
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
1168class 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
1177public:
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.
1189class 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
1208public:
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.
1228class 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
1243public:
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.
1260class 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
1274public:
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.
1299class 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
1317public:
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
1336template<typename RegionTy>
1337const RegionTy* MemRegion::getAs() const {
1338  if (const auto *RT = dyn_cast<RegionTy>(this))
1339    return RT;
1340
1341  return nullptr;
1342}
1343
1344template <typename RegionTy>
1345LLVM_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
1353class 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
1374public:
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
1533private:
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
1561inline 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.
1570class 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
1581public:
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//===----------------------------------------------------------------------===//
1610inline 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