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/Optional.h"
34#include "llvm/ADT/PointerIntPair.h"
35#include "llvm/Support/Allocator.h"
36#include "llvm/Support/Casting.h"
37#include <cassert>
38#include <cstdint>
39#include <limits>
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 const MemRegion *getRegion() const { return R; }
78
79 bool hasSymbolicOffset() const { return Offset == Symbolic; }
80
81 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
173 virtual bool isBoundable() const { return false; }
174
175 /// Get descriptive name for memory region. The name is obtained from
176 /// the variable/field declaration retrieved from the memory region.
177 /// Regions that point to an element of an array are returned as: "arr[0]".
178 /// Regions that point to a struct are returned as: "st.var".
179 //
180 /// \param UseQuotes Set if the name should be quoted.
181 ///
182 /// \returns variable name for memory region
183 std::string getDescriptiveName(bool UseQuotes = true) const;
184
185 /// Retrieve source range from memory region. The range retrieval
186 /// is based on the decl obtained from the memory region.
187 /// For a VarRegion the range of the base region is returned.
188 /// For a FieldRegion the range of the field is returned.
189 /// If no declaration is found, an empty source range is returned.
190 /// The client is responsible for checking if the returned range is valid.
191 ///
192 /// \returns source range for declaration retrieved from memory region
193 SourceRange sourceRange() const;
194};
195
196/// MemSpaceRegion - A memory region that represents a "memory space";
197/// for example, the set of global variables, the stack frame, etc.
198class MemSpaceRegion : public MemRegion {
199protected:
200 MemRegionManager *Mgr;
201
202 MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) {
203 assert(classof(this));
204 assert(mgr);
205 }
206
207 MemRegionManager* getMemRegionManager() const override { return Mgr; }
208
209public:
210 bool isBoundable() const override { return false; }
211
212 void Profile(llvm::FoldingSetNodeID &ID) const override;
213
214 static bool classof(const MemRegion *R) {
215 Kind k = R->getKind();
216 return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
217 }
218};
219
220/// CodeSpaceRegion - The memory space that holds the executable code of
221/// functions and blocks.
222class CodeSpaceRegion : public MemSpaceRegion {
223 friend class MemRegionManager;
224
225 CodeSpaceRegion(MemRegionManager *mgr)
226 : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
227
228public:
229 void dumpToStream(raw_ostream &os) const override;
230
231 static bool classof(const MemRegion *R) {
232 return R->getKind() == CodeSpaceRegionKind;
233 }
234};
235
236class GlobalsSpaceRegion : public MemSpaceRegion {
237 virtual void anchor();
238
239protected:
240 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) {
241 assert(classof(this));
242 }
243
244public:
245 static bool classof(const MemRegion *R) {
246 Kind k = R->getKind();
247 return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
248 }
249};
250
251/// The region of the static variables within the current CodeTextRegion
252/// scope.
253///
254/// Currently, only the static locals are placed there, so we know that these
255/// variables do not get invalidated by calls to other functions.
256class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
257 friend class MemRegionManager;
258
259 const CodeTextRegion *CR;
260
261 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
262 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
263 assert(cr);
264 }
265
266public:
267 void Profile(llvm::FoldingSetNodeID &ID) const override;
268
269 void dumpToStream(raw_ostream &os) const override;
270
271 const CodeTextRegion *getCodeRegion() const { return CR; }
272
273 static bool classof(const MemRegion *R) {
274 return R->getKind() == StaticGlobalSpaceRegionKind;
275 }
276};
277
278/// The region for all the non-static global variables.
279///
280/// This class is further split into subclasses for efficient implementation of
281/// invalidating a set of related global values as is done in
282/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
283/// globals, we invalidate the whole parent region).
284class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
285 void anchor() override;
286
287protected:
288 NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
289 : GlobalsSpaceRegion(mgr, k) {
290 assert(classof(this));
291 }
292
293public:
294 static bool classof(const MemRegion *R) {
295 Kind k = R->getKind();
296 return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
297 k <= END_NON_STATIC_GLOBAL_MEMSPACES;
298 }
299};
300
301/// The region containing globals which are defined in system/external
302/// headers and are considered modifiable by system calls (ex: errno).
303class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
304 friend class MemRegionManager;
305
306 GlobalSystemSpaceRegion(MemRegionManager *mgr)
307 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
308
309public:
310 void dumpToStream(raw_ostream &os) const override;
311
312 static bool classof(const MemRegion *R) {
313 return R->getKind() == GlobalSystemSpaceRegionKind;
314 }
315};
316
317/// The region containing globals which are considered not to be modified
318/// or point to data which could be modified as a result of a function call
319/// (system or internal). Ex: Const global scalars would be modeled as part of
320/// this region. This region also includes most system globals since they have
321/// low chance of being modified.
322class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
323 friend class MemRegionManager;
324
325 GlobalImmutableSpaceRegion(MemRegionManager *mgr)
326 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
327
328public:
329 void dumpToStream(raw_ostream &os) const override;
330
331 static bool classof(const MemRegion *R) {
332 return R->getKind() == GlobalImmutableSpaceRegionKind;
333 }
334};
335
336/// The region containing globals which can be modified by calls to
337/// "internally" defined functions - (for now just) functions other then system
338/// calls.
339class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
340 friend class MemRegionManager;
341
342 GlobalInternalSpaceRegion(MemRegionManager *mgr)
343 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
344
345public:
346 void dumpToStream(raw_ostream &os) const override;
347
348 static bool classof(const MemRegion *R) {
349 return R->getKind() == GlobalInternalSpaceRegionKind;
350 }
351};
352
353class HeapSpaceRegion : public MemSpaceRegion {
354 friend class MemRegionManager;
355
356 HeapSpaceRegion(MemRegionManager *mgr)
357 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
358
359public:
360 void dumpToStream(raw_ostream &os) const override;
361
362 static bool classof(const MemRegion *R) {
363 return R->getKind() == HeapSpaceRegionKind;
364 }
365};
366
367class UnknownSpaceRegion : public MemSpaceRegion {
368 friend class MemRegionManager;
369
370 UnknownSpaceRegion(MemRegionManager *mgr)
371 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
372
373public:
374 void dumpToStream(raw_ostream &os) const override;
375
376 static bool classof(const MemRegion *R) {
377 return R->getKind() == UnknownSpaceRegionKind;
378 }
379};
380
381class StackSpaceRegion : public MemSpaceRegion {
382 virtual void anchor();
383
384 const StackFrameContext *SFC;
385
386protected:
387 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
388 : MemSpaceRegion(mgr, k), SFC(sfc) {
389 assert(classof(this));
390 assert(sfc);
391 }
392
393public:
394 const StackFrameContext *getStackFrame() const { return SFC; }
395
396 void Profile(llvm::FoldingSetNodeID &ID) const override;
397
398 static bool classof(const MemRegion *R) {
399 Kind k = R->getKind();
400 return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
401 }
402};
403
404class StackLocalsSpaceRegion : public StackSpaceRegion {
405 friend class MemRegionManager;
406
407 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
408 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
409
410public:
411 void dumpToStream(raw_ostream &os) const override;
412
413 static bool classof(const MemRegion *R) {
414 return R->getKind() == StackLocalsSpaceRegionKind;
415 }
416};
417
418class StackArgumentsSpaceRegion : public StackSpaceRegion {
419private:
420 friend class MemRegionManager;
421
422 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
423 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
424
425public:
426 void dumpToStream(raw_ostream &os) const override;
427
428 static bool classof(const MemRegion *R) {
429 return R->getKind() == StackArgumentsSpaceRegionKind;
430 }
431};
432
433/// SubRegion - A region that subsets another larger region. Most regions
434/// are subclasses of SubRegion.
435class SubRegion : public MemRegion {
436 virtual void anchor();
437
438protected:
439 const MemRegion* superRegion;
440
441 SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
442 assert(classof(this));
443 assert(sReg);
444 }
445
446public:
447 const MemRegion* getSuperRegion() const {
448 return superRegion;
449 }
450
451 /// getExtent - Returns the size of the region in bytes.
452 virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
453 return UnknownVal();
454 }
455
456 MemRegionManager* getMemRegionManager() const override;
457
458 bool isSubRegionOf(const MemRegion* R) const override;
459
460 static bool classof(const MemRegion* R) {
461 return R->getKind() > END_MEMSPACES;
462 }
463};
464
465//===----------------------------------------------------------------------===//
466// MemRegion subclasses.
467//===----------------------------------------------------------------------===//
468
469/// AllocaRegion - A region that represents an untyped blob of bytes created
470/// by a call to 'alloca'.
471class AllocaRegion : public SubRegion {
472 friend class MemRegionManager;
473
474 // Block counter. Used to distinguish different pieces of memory allocated by
475 // alloca at the same call site.
476 unsigned Cnt;
477
478 const Expr *Ex;
479
480 AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
481 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
482 assert(Ex);
483 }
484
485 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
486 unsigned Cnt, const MemRegion *superRegion);
487
488public:
489 const Expr *getExpr() const { return Ex; }
490
491 bool isBoundable() const override { return true; }
492
493 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
494
495 void Profile(llvm::FoldingSetNodeID& ID) const override;
496
497 void dumpToStream(raw_ostream &os) const override;
498
499 static bool classof(const MemRegion* R) {
500 return R->getKind() == AllocaRegionKind;
501 }
502};
503
504/// TypedRegion - An abstract class representing regions that are typed.
505class TypedRegion : public SubRegion {
506 void anchor() override;
507
508protected:
509 TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
510 assert(classof(this));
511 }
512
513public:
514 virtual QualType getLocationType() const = 0;
515
516 QualType getDesugaredLocationType(ASTContext &Context) const {
517 return getLocationType().getDesugaredType(Context);
518 }
519
520 bool isBoundable() const override { return true; }
521
522 static bool classof(const MemRegion* R) {
523 unsigned k = R->getKind();
524 return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
525 }
526};
527
528/// TypedValueRegion - An abstract class representing regions having a typed value.
529class TypedValueRegion : public TypedRegion {
530 void anchor() override;
531
532protected:
533 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
534 assert(classof(this));
535 }
536
537public:
538 virtual QualType getValueType() const = 0;
539
540 QualType getLocationType() const override {
541 // FIXME: We can possibly optimize this later to cache this value.
542 QualType T = getValueType();
543 ASTContext &ctx = getContext();
544 if (T->getAs<ObjCObjectType>())
545 return ctx.getObjCObjectPointerType(T);
546 return ctx.getPointerType(getValueType());
547 }
548
549 QualType getDesugaredValueType(ASTContext &Context) const {
550 QualType T = getValueType();
551 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
552 }
553
554 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
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 const BlockDecl *getDecl() const {
652 return BD;
653 }
654
655 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
656
657 void dumpToStream(raw_ostream &os) const override;
658
659 void Profile(llvm::FoldingSetNodeID& ID) const override;
660
661 static bool classof(const MemRegion* R) {
662 return R->getKind() == BlockCodeRegionKind;
663 }
664};
665
666/// BlockDataRegion - A region that represents a block instance.
667/// Blocks are represented with two kinds of regions. BlockCodeRegions
668/// represent the "code", while BlockDataRegions represent instances of blocks,
669/// which correspond to "code+data". The distinction is important, because
670/// like a closure a block captures the values of externally referenced
671/// variables.
672class BlockDataRegion : public TypedRegion {
673 friend class MemRegionManager;
674
675 const BlockCodeRegion *BC;
676 const LocationContext *LC; // Can be null
677 unsigned BlockCount;
678 void *ReferencedVars = nullptr;
679 void *OriginalVars = nullptr;
680
681 BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
682 unsigned count, const MemSpaceRegion *sreg)
683 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
684 BlockCount(count) {
685 assert(bc);
686 assert(lc);
687 assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
688 isa<StackLocalsSpaceRegion>(sreg) ||
689 isa<UnknownSpaceRegion>(sreg));
690 }
691
692 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
693 const LocationContext *, unsigned,
694 const MemRegion *);
695
696public:
697 const BlockCodeRegion *getCodeRegion() const { return BC; }
698
699 const BlockDecl *getDecl() const { return BC->getDecl(); }
700
701 QualType getLocationType() const override { return BC->getLocationType(); }
702
703 class referenced_vars_iterator {
704 const MemRegion * const *R;
705 const MemRegion * const *OriginalR;
706
707 public:
708 explicit referenced_vars_iterator(const MemRegion * const *r,
709 const MemRegion * const *originalR)
710 : R(r), OriginalR(originalR) {}
711
712 const VarRegion *getCapturedRegion() const {
713 return cast<VarRegion>(*R);
714 }
715
716 const VarRegion *getOriginalRegion() const {
717 return cast<VarRegion>(*OriginalR);
718 }
719
720 bool operator==(const referenced_vars_iterator &I) const {
721 assert((R == nullptr) == (I.R == nullptr));
722 return I.R == R;
723 }
724
725 bool operator!=(const referenced_vars_iterator &I) const {
726 assert((R == nullptr) == (I.R == nullptr));
727 return I.R != R;
728 }
729
730 referenced_vars_iterator &operator++() {
731 ++R;
732 ++OriginalR;
733 return *this;
734 }
735 };
736
737 /// Return the original region for a captured region, if
738 /// one exists.
739 const VarRegion *getOriginalRegion(const VarRegion *VR) const;
740
741 referenced_vars_iterator referenced_vars_begin() const;
742 referenced_vars_iterator referenced_vars_end() const;
743
744 void dumpToStream(raw_ostream &os) const override;
745
746 void Profile(llvm::FoldingSetNodeID& ID) const override;
747
748 static bool classof(const MemRegion* R) {
749 return R->getKind() == BlockDataRegionKind;
750 }
751
752private:
753 void LazyInitializeReferencedVars();
754 std::pair<const VarRegion *, const VarRegion *>
755 getCaptureRegions(const VarDecl *VD);
756};
757
758/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
759/// classes, SymbolicRegion represents a region that serves as an alias for
760/// either a real region, a NULL pointer, etc. It essentially is used to
761/// map the concept of symbolic values into the domain of regions. Symbolic
762/// regions do not need to be typed.
763class SymbolicRegion : public SubRegion {
764 friend class MemRegionManager;
765
766 const SymbolRef sym;
767
768 SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
769 : SubRegion(sreg, SymbolicRegionKind), sym(s) {
770 // Because pointer arithmetic is represented by ElementRegion layers,
771 // the base symbol here should not contain any arithmetic.
772 assert(s && isa<SymbolData>(s));
773 assert(s->getType()->isAnyPointerType() ||
774 s->getType()->isReferenceType() ||
775 s->getType()->isBlockPointerType());
776 assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
777 }
778
779public:
780 SymbolRef getSymbol() const { return sym; }
781
782 bool isBoundable() const override { return true; }
783
784 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
785
786 void Profile(llvm::FoldingSetNodeID& ID) const override;
787
788 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
789 SymbolRef sym,
790 const MemRegion* superRegion);
791
792 void dumpToStream(raw_ostream &os) const override;
793
794 static bool classof(const MemRegion* R) {
795 return R->getKind() == SymbolicRegionKind;
796 }
797};
798
799/// StringRegion - Region associated with a StringLiteral.
800class StringRegion : public TypedValueRegion {
801 friend class MemRegionManager;
802
803 const StringLiteral *Str;
804
805 StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
806 : TypedValueRegion(sreg, StringRegionKind), Str(str) {
807 assert(str);
808 }
809
810 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
811 const StringLiteral *Str,
812 const MemRegion *superRegion);
813
814public:
815 const StringLiteral *getStringLiteral() const { return Str; }
816
817 QualType getValueType() const override { return Str->getType(); }
818
819 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
820
821 bool isBoundable() const override { return false; }
822
823 void Profile(llvm::FoldingSetNodeID& ID) const override {
824 ProfileRegion(ID, Str, superRegion);
825 }
826
827 void dumpToStream(raw_ostream &os) const override;
828
829 static bool classof(const MemRegion* R) {
830 return R->getKind() == StringRegionKind;
831 }
832};
833
834/// The region associated with an ObjCStringLiteral.
835class ObjCStringRegion : public TypedValueRegion {
836 friend class MemRegionManager;
837
838 const ObjCStringLiteral *Str;
839
840 ObjCStringRegion(const ObjCStringLiteral *str,
841 const GlobalInternalSpaceRegion *sreg)
842 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
843 assert(str);
844 }
845
846 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
847 const ObjCStringLiteral *Str,
848 const MemRegion *superRegion);
849
850public:
851 const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
852
853 QualType getValueType() const override { return Str->getType(); }
854
855 bool isBoundable() const override { return false; }
856
857 void Profile(llvm::FoldingSetNodeID& ID) const override {
858 ProfileRegion(ID, Str, superRegion);
859 }
860
861 void dumpToStream(raw_ostream &os) const override;
862
863 static bool classof(const MemRegion* R) {
864 return R->getKind() == ObjCStringRegionKind;
865 }
866};
867
868/// CompoundLiteralRegion - A memory region representing a compound literal.
869/// Compound literals are essentially temporaries that are stack allocated
870/// or in the global constant pool.
871class CompoundLiteralRegion : public TypedValueRegion {
872 friend class MemRegionManager;
873
874 const CompoundLiteralExpr *CL;
875
876 CompoundLiteralRegion(const CompoundLiteralExpr *cl,
877 const MemSpaceRegion *sReg)
878 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
879 assert(cl);
880 assert(isa<GlobalInternalSpaceRegion>(sReg) ||
881 isa<StackLocalsSpaceRegion>(sReg));
882 }
883
884 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
885 const CompoundLiteralExpr *CL,
886 const MemRegion* superRegion);
887
888public:
889 QualType getValueType() const override { return CL->getType(); }
890
891 bool isBoundable() const override { return !CL->isFileScope(); }
892
893 void Profile(llvm::FoldingSetNodeID& ID) const override;
894
895 void dumpToStream(raw_ostream &os) const override;
896
897 const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
898
899 static bool classof(const MemRegion* R) {
900 return R->getKind() == CompoundLiteralRegionKind;
901 }
902};
903
904class DeclRegion : public TypedValueRegion {
905protected:
906 const ValueDecl *D;
907
908 DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
909 : TypedValueRegion(sReg, k), D(d) {
910 assert(classof(this));
911 assert(d && d->isCanonicalDecl());
912 }
913
914 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
915 const MemRegion* superRegion, Kind k);
916
917public:
918 const ValueDecl *getDecl() const { return D; }
919 void Profile(llvm::FoldingSetNodeID& ID) const override;
920
921 static bool classof(const MemRegion* R) {
922 unsigned k = R->getKind();
923 return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
924 }
925};
926
927class VarRegion : public DeclRegion {
928 friend class MemRegionManager;
929
930 // Constructors and private methods.
931 VarRegion(const VarDecl *vd, const MemRegion *sReg)
932 : DeclRegion(vd, sReg, VarRegionKind) {
933 // VarRegion appears in unknown space when it's a block variable as seen
934 // from a block using it, when this block is analyzed at top-level.
935 // Other block variables appear within block data regions,
936 // which, unlike everything else on this list, are not memory spaces.
937 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
938 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
939 }
940
941 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
942 const MemRegion *superRegion) {
943 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
944 }
945
946public:
947 void Profile(llvm::FoldingSetNodeID& ID) const override;
948
949 const VarDecl *getDecl() const { return cast<VarDecl>(D); }
950
951 const StackFrameContext *getStackFrame() const;
952
953 QualType getValueType() const override {
954 // FIXME: We can cache this if needed.
955 return getDecl()->getType();
956 }
957
958 void dumpToStream(raw_ostream &os) const override;
959
960 bool canPrintPrettyAsExpr() const override;
961
962 void printPrettyAsExpr(raw_ostream &os) const override;
963
964 static bool classof(const MemRegion* R) {
965 return R->getKind() == VarRegionKind;
966 }
967};
968
969/// CXXThisRegion - Represents the region for the implicit 'this' parameter
970/// in a call to a C++ method. This region doesn't represent the object
971/// referred to by 'this', but rather 'this' itself.
972class CXXThisRegion : public TypedValueRegion {
973 friend class MemRegionManager;
974
975 CXXThisRegion(const PointerType *thisPointerTy,
976 const StackArgumentsSpaceRegion *sReg)
977 : TypedValueRegion(sReg, CXXThisRegionKind),
978 ThisPointerTy(thisPointerTy) {
979 assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
980 "Invalid region type!");
981 }
982
983 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
984 const PointerType *PT,
985 const MemRegion *sReg);
986
987public:
988 void Profile(llvm::FoldingSetNodeID &ID) const override;
989
990 QualType getValueType() const override {
991 return QualType(ThisPointerTy, 0);
992 }
993
994 void dumpToStream(raw_ostream &os) const override;
995
996 static bool classof(const MemRegion* R) {
997 return R->getKind() == CXXThisRegionKind;
998 }
999
1000private:
1001 const PointerType *ThisPointerTy;
1002};
1003
1004class FieldRegion : public DeclRegion {
1005 friend class MemRegionManager;
1006
1007 FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
1008 : DeclRegion(fd, sReg, FieldRegionKind) {}
1009
1010 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
1011 const MemRegion* superRegion) {
1012 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
1013 }
1014
1015public:
1016 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
1017
1018 QualType getValueType() const override {
1019 // FIXME: We can cache this if needed.
1020 return getDecl()->getType();
1021 }
1022
1023 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
1024
1025 void dumpToStream(raw_ostream &os) const override;
1026
1027 bool canPrintPretty() const override;
1028 void printPretty(raw_ostream &os) const override;
1029 bool canPrintPrettyAsExpr() const override;
1030 void printPrettyAsExpr(raw_ostream &os) const override;
1031
1032 static bool classof(const MemRegion* R) {
1033 return R->getKind() == FieldRegionKind;
1034 }
1035};
1036
1037class ObjCIvarRegion : public DeclRegion {
1038 friend class MemRegionManager;
1039
1040 ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1041
1042 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1043 const MemRegion* superRegion);
1044
1045public:
1046 const ObjCIvarDecl *getDecl() const;
1047 QualType getValueType() const override;
1048
1049 bool canPrintPrettyAsExpr() const override;
1050 void printPrettyAsExpr(raw_ostream &os) const override;
1051
1052 void dumpToStream(raw_ostream &os) const override;
1053
1054 static bool classof(const MemRegion* R) {
1055 return R->getKind() == ObjCIvarRegionKind;
1056 }
1057};
1058
1059//===----------------------------------------------------------------------===//
1060// Auxiliary data classes for use with MemRegions.
1061//===----------------------------------------------------------------------===//
1062
1063class RegionRawOffset {
1064 friend class ElementRegion;
1065
1066 const MemRegion *Region;
1067 CharUnits Offset;
1068
1069 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1070 : Region(reg), Offset(offset) {}
1071
1072public:
1073 // FIXME: Eventually support symbolic offsets.
1074 CharUnits getOffset() const { return Offset; }
1075 const MemRegion *getRegion() const { return Region; }
1076
1077 void dumpToStream(raw_ostream &os) const;
1078 void dump() const;
1079};
1080
1081/// ElementRegion is used to represent both array elements and casts.
1082class ElementRegion : public TypedValueRegion {
1083 friend class MemRegionManager;
1084
1085 QualType ElementType;
1086 NonLoc Index;
1087
1088 ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1089 : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1090 Index(Idx) {
1091 assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1092 Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1093 "The index must be signed");
1094 assert(!elementType.isNull() && !elementType->isVoidType() &&
1095 "Invalid region type!");
1096 }
1097
1098 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1099 SVal Idx, const MemRegion* superRegion);
1100
1101public:
1102 NonLoc getIndex() const { return Index; }
1103
1104 QualType getValueType() const override { return ElementType; }
1105
1106 QualType getElementType() const { return ElementType; }
1107
1108 /// Compute the offset within the array. The array might also be a subobject.
1109 RegionRawOffset getAsArrayOffset() const;
1110
1111 void dumpToStream(raw_ostream &os) const override;
1112
1113 void Profile(llvm::FoldingSetNodeID& ID) const override;
1114
1115 static bool classof(const MemRegion* R) {
1116 return R->getKind() == ElementRegionKind;
1117 }
1118};
1119
1120// C++ temporary object associated with an expression.
1121class CXXTempObjectRegion : public TypedValueRegion {
1122 friend class MemRegionManager;
1123
1124 Expr const *Ex;
1125
1126 CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1127 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1128 assert(E);
1129 assert(isa<StackLocalsSpaceRegion>(sReg) ||
1130 isa<GlobalInternalSpaceRegion>(sReg));
1131 }
1132
1133 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1134 Expr const *E, const MemRegion *sReg);
1135
1136public:
1137 const Expr *getExpr() const { return Ex; }
1138
1139 QualType getValueType() const override { return Ex->getType(); }
1140
1141 void dumpToStream(raw_ostream &os) const override;
1142
1143 void Profile(llvm::FoldingSetNodeID &ID) const override;
1144
1145 static bool classof(const MemRegion* R) {
1146 return R->getKind() == CXXTempObjectRegionKind;
1147 }
1148};
1149
1150// CXXBaseObjectRegion represents a base object within a C++ object. It is
1151// identified by the base class declaration and the region of its parent object.
1152class CXXBaseObjectRegion : public TypedValueRegion {
1153 friend class MemRegionManager;
1154
1155 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1156
1157 CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1158 const SubRegion *SReg)
1159 : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1160 assert(RD);
1161 }
1162
1163 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1164 bool IsVirtual, const MemRegion *SReg);
1165
1166public:
1167 const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1168 bool isVirtual() const { return Data.getInt(); }
1169
1170 QualType getValueType() const override;
1171
1172 void dumpToStream(raw_ostream &os) const override;
1173
1174 void Profile(llvm::FoldingSetNodeID &ID) const override;
1175
1176 bool canPrintPrettyAsExpr() const override;
1177
1178 void printPrettyAsExpr(raw_ostream &os) const override;
1179
1180 static bool classof(const MemRegion *region) {
1181 return region->getKind() == CXXBaseObjectRegionKind;
1182 }
1183};
1184
1185// CXXDerivedObjectRegion represents a derived-class object that surrounds
1186// a C++ object. It is identified by the derived class declaration and the
1187// region of its parent object. It is a bit counter-intuitive (but not otherwise
1188// unseen) that this region represents a larger segment of memory that its
1189// super-region.
1190class CXXDerivedObjectRegion : public TypedValueRegion {
1191 friend class MemRegionManager;
1192
1193 const CXXRecordDecl *DerivedD;
1194
1195 CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1196 : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1197 assert(DerivedD);
1198 // In case of a concrete region, it should always be possible to model
1199 // the base-to-derived cast by undoing a previous derived-to-base cast,
1200 // otherwise the cast is most likely ill-formed.
1201 assert(SReg->getSymbolicBase() &&
1202 "Should have unwrapped a base region instead!");
1203 }
1204
1205 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1206 const MemRegion *SReg);
1207
1208public:
1209 const CXXRecordDecl *getDecl() const { return DerivedD; }
1210
1211 QualType getValueType() const override;
1212
1213 void dumpToStream(raw_ostream &os) const override;
1214
1215 void Profile(llvm::FoldingSetNodeID &ID) const override;
1216
1217 bool canPrintPrettyAsExpr() const override;
1218
1219 void printPrettyAsExpr(raw_ostream &os) const override;
1220
1221 static bool classof(const MemRegion *region) {
1222 return region->getKind() == CXXDerivedObjectRegionKind;
1223 }
1224};
1225
1226template<typename RegionTy>
1227const RegionTy* MemRegion::getAs() const {
1228 if (const auto *RT = dyn_cast<RegionTy>(this))
1229 return RT;
1230
1231 return nullptr;
1232}
1233
1234//===----------------------------------------------------------------------===//
1235// MemRegionManager - Factory object for creating regions.
1236//===----------------------------------------------------------------------===//
1237
1238class MemRegionManager {
1239 ASTContext &C;
1240 llvm::BumpPtrAllocator& A;
1241 llvm::FoldingSet<MemRegion> Regions;
1242
1243 GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1244 GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1245 GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1246
1247 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1248 StackLocalsSpaceRegions;
1249 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1250 StackArgumentsSpaceRegions;
1251 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1252 StaticsGlobalSpaceRegions;
1253
1254 HeapSpaceRegion *heap = nullptr;
1255 UnknownSpaceRegion *unknown = nullptr;
1256 CodeSpaceRegion *code = nullptr;
1257
1258public:
1259 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {}
1260 ~MemRegionManager();
1261
1262 ASTContext &getContext() { return C; }
1263
1264 llvm::BumpPtrAllocator &getAllocator() { return A; }
1265
1266 /// getStackLocalsRegion - Retrieve the memory region associated with the
1267 /// specified stack frame.
1268 const StackLocalsSpaceRegion *
1269 getStackLocalsRegion(const StackFrameContext *STC);
1270
1271 /// getStackArgumentsRegion - Retrieve the memory region associated with
1272 /// function/method arguments of the specified stack frame.
1273 const StackArgumentsSpaceRegion *
1274 getStackArgumentsRegion(const StackFrameContext *STC);
1275
1276 /// getGlobalsRegion - Retrieve the memory region associated with
1277 /// global variables.
1278 const GlobalsSpaceRegion *getGlobalsRegion(
1279 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1280 const CodeTextRegion *R = nullptr);
1281
1282 /// getHeapRegion - Retrieve the memory region associated with the
1283 /// generic "heap".
1284 const HeapSpaceRegion *getHeapRegion();
1285
1286 /// getUnknownRegion - Retrieve the memory region associated with unknown
1287 /// memory space.
1288 const UnknownSpaceRegion *getUnknownRegion();
1289
1290 const CodeSpaceRegion *getCodeRegion();
1291
1292 /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1293 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1294 const LocationContext *LC);
1295
1296 /// getCompoundLiteralRegion - Retrieve the region associated with a
1297 /// given CompoundLiteral.
1298 const CompoundLiteralRegion*
1299 getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1300 const LocationContext *LC);
1301
1302 /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1303 /// parameter 'this'.
1304 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1305 const LocationContext *LC);
1306
1307 /// Retrieve or create a "symbolic" memory region.
1308 const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1309
1310 /// Return a unique symbolic region belonging to heap memory space.
1311 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1312
1313 const StringRegion *getStringRegion(const StringLiteral *Str);
1314
1315 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1316
1317 /// getVarRegion - Retrieve or create the memory region associated with
1318 /// a specified VarDecl and LocationContext.
1319 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1320
1321 /// getVarRegion - Retrieve or create the memory region associated with
1322 /// a specified VarDecl and super region.
1323 const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
1324
1325 /// getElementRegion - Retrieve the memory region associated with the
1326 /// associated element type, index, and super region.
1327 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1328 const SubRegion *superRegion,
1329 ASTContext &Ctx);
1330
1331 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1332 const SubRegion *superRegion) {
1333 return getElementRegion(ER->getElementType(), ER->getIndex(),
1334 superRegion, ER->getContext());
1335 }
1336
1337 /// getFieldRegion - Retrieve or create the memory region associated with
1338 /// a specified FieldDecl. 'superRegion' corresponds to the containing
1339 /// memory region (which typically represents the memory representing
1340 /// a structure or class).
1341 const FieldRegion *getFieldRegion(const FieldDecl *fd,
1342 const SubRegion* superRegion);
1343
1344 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1345 const SubRegion *superRegion) {
1346 return getFieldRegion(FR->getDecl(), superRegion);
1347 }
1348
1349 /// getObjCIvarRegion - Retrieve or create the memory region associated with
1350 /// a specified Objective-c instance variable. 'superRegion' corresponds
1351 /// to the containing region (which typically represents the Objective-C
1352 /// object).
1353 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1354 const SubRegion* superRegion);
1355
1356 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1357 LocationContext const *LC);
1358
1359 /// Create a CXXBaseObjectRegion with the given base class for region
1360 /// \p Super.
1361 ///
1362 /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1363 const CXXBaseObjectRegion *
1364 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1365 bool IsVirtual);
1366
1367 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1368 /// super region.
1369 const CXXBaseObjectRegion *
1370 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1371 const SubRegion *superRegion) {
1372 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1373 baseReg->isVirtual());
1374 }
1375
1376 /// Create a CXXDerivedObjectRegion with the given derived class for region
1377 /// \p Super. This should not be used for casting an existing
1378 /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1379 /// should be removed.
1380 const CXXDerivedObjectRegion *
1381 getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1382 const SubRegion *Super);
1383
1384 const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1385 const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1386 CanQualType locTy,
1387 AnalysisDeclContext *AC);
1388
1389 /// getBlockDataRegion - Get the memory region associated with an instance
1390 /// of a block. Unlike many other MemRegions, the LocationContext*
1391 /// argument is allowed to be NULL for cases where we have no known
1392 /// context.
1393 const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1394 const LocationContext *lc,
1395 unsigned blockCount);
1396
1397 /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1398 /// by static references. This differs from getCXXTempObjectRegion in the
1399 /// super-region used.
1400 const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1401
1402private:
1403 template <typename RegionTy, typename SuperTy,
1404 typename Arg1Ty>
1405 RegionTy* getSubRegion(const Arg1Ty arg1,
1406 const SuperTy* superRegion);
1407
1408 template <typename RegionTy, typename SuperTy,
1409 typename Arg1Ty, typename Arg2Ty>
1410 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1411 const SuperTy* superRegion);
1412
1413 template <typename RegionTy, typename SuperTy,
1414 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1415 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1416 const Arg3Ty arg3,
1417 const SuperTy* superRegion);
1418
1419 template <typename REG>
1420 const REG* LazyAllocate(REG*& region);
1421
1422 template <typename REG, typename ARG>
1423 const REG* LazyAllocate(REG*& region, ARG a);
1424};
1425
1426//===----------------------------------------------------------------------===//
1427// Out-of-line member definitions.
1428//===----------------------------------------------------------------------===//
1429
1430inline ASTContext &MemRegion::getContext() const {
1431 return getMemRegionManager()->getContext();
1432}
1433
1434//===----------------------------------------------------------------------===//
1435// Means for storing region/symbol handling traits.
1436//===----------------------------------------------------------------------===//
1437
1438/// Information about invalidation for a particular region/symbol.
1439class RegionAndSymbolInvalidationTraits {
1440 using StorageTypeForKinds = unsigned char;
1441
1442 llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1443 llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1444
1445 using const_region_iterator =
1446 llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1447 using const_symbol_iterator =
1448 llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1449
1450public:
1451 /// Describes different invalidation traits.
1452 enum InvalidationKinds {
1453 /// Tells that a region's contents is not changed.
1454 TK_PreserveContents = 0x1,
1455
1456 /// Suppress pointer-escaping of a region.
1457 TK_SuppressEscape = 0x2,
1458
1459 // Do not invalidate super region.
1460 TK_DoNotInvalidateSuperRegion = 0x4,
1461
1462 /// When applied to a MemSpaceRegion, indicates the entire memory space
1463 /// should be invalidated.
1464 TK_EntireMemSpace = 0x8
1465
1466 // Do not forget to extend StorageTypeForKinds if number of traits exceed
1467 // the number of bits StorageTypeForKinds can store.
1468 };
1469
1470 void setTrait(SymbolRef Sym, InvalidationKinds IK);
1471 void setTrait(const MemRegion *MR, InvalidationKinds IK);
1472 bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1473 bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1474};
1475
1476//===----------------------------------------------------------------------===//
1477// Pretty-printing regions.
1478//===----------------------------------------------------------------------===//
1479inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1480 R->dumpToStream(os);
1481 return os;
1482}
1483
1484} // namespace ento
1485
1486} // namespace clang
1487
1488#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
1489