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