1 //==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines MemRegion and its subclasses. MemRegion defines a
11 // partially-typed abstraction of memory useful for path-sensitive dataflow
12 // analyses.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
17 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
18
19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/CharUnits.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclObjC.h"
23 #include "clang/AST/DeclarationName.h"
24 #include "clang/AST/Expr.h"
25 #include "clang/AST/ExprObjC.h"
26 #include "clang/AST/Type.h"
27 #include "clang/Analysis/AnalysisDeclContext.h"
28 #include "clang/Basic/LLVM.h"
29 #include "clang/Basic/SourceLocation.h"
30 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
31 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
32 #include "llvm/ADT/DenseMap.h"
33 #include "llvm/ADT/FoldingSet.h"
34 #include "llvm/ADT/Optional.h"
35 #include "llvm/ADT/PointerIntPair.h"
36 #include "llvm/Support/Allocator.h"
37 #include "llvm/Support/Casting.h"
38 #include <cassert>
39 #include <cstdint>
40 #include <limits>
41 #include <string>
42 #include <utility>
43
44 namespace clang {
45
46 class AnalysisDeclContext;
47 class CXXRecordDecl;
48 class Decl;
49 class LocationContext;
50 class StackFrameContext;
51
52 namespace ento {
53
54 class CodeTextRegion;
55 class MemRegion;
56 class MemRegionManager;
57 class MemSpaceRegion;
58 class SValBuilder;
59 class SymbolicRegion;
60 class VarRegion;
61
62 /// Represent a region's offset within the top level base region.
63 class RegionOffset {
64 /// The base region.
65 const MemRegion *R = nullptr;
66
67 /// The bit offset within the base region. Can be negative.
68 int64_t Offset;
69
70 public:
71 // We're using a const instead of an enumeration due to the size required;
72 // Visual Studio will only create enumerations of size int, not long long.
73 static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
74
75 RegionOffset() = default;
RegionOffset(const MemRegion * r,int64_t off)76 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
77
getRegion()78 const MemRegion *getRegion() const { return R; }
79
hasSymbolicOffset()80 bool hasSymbolicOffset() const { return Offset == Symbolic; }
81
getOffset()82 int64_t getOffset() const {
83 assert(!hasSymbolicOffset());
84 return Offset;
85 }
86
isValid()87 bool isValid() const { return R; }
88 };
89
90 //===----------------------------------------------------------------------===//
91 // Base region classes.
92 //===----------------------------------------------------------------------===//
93
94 /// MemRegion - The root abstract class for all memory regions.
95 class MemRegion : public llvm::FoldingSetNode {
96 public:
97 enum Kind {
98 #define REGION(Id, Parent) Id ## Kind,
99 #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
100 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
101 };
102
103 private:
104 const Kind kind;
105 mutable Optional<RegionOffset> cachedOffset;
106
107 protected:
MemRegion(Kind k)108 MemRegion(Kind k) : kind(k) {}
109 virtual ~MemRegion();
110
111 public:
112 ASTContext &getContext() const;
113
114 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
115
116 virtual MemRegionManager* getMemRegionManager() const = 0;
117
118 const MemSpaceRegion *getMemorySpace() const;
119
120 const MemRegion *getBaseRegion() const;
121
122 /// Recursively retrieve the region of the most derived class instance of
123 /// regions of C++ base class instances.
124 const MemRegion *getMostDerivedObjectRegion() const;
125
126 /// Check if the region is a subregion of the given region.
127 /// Each region is a subregion of itself.
128 virtual bool isSubRegionOf(const MemRegion *R) const;
129
130 const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
131
132 /// If this is a symbolic region, returns the region. Otherwise,
133 /// goes up the base chain looking for the first symbolic base region.
134 const SymbolicRegion *getSymbolicBase() const;
135
136 bool hasGlobalsOrParametersStorage() const;
137
138 bool hasStackStorage() const;
139
140 bool hasStackNonParametersStorage() const;
141
142 bool hasStackParametersStorage() const;
143
144 /// Compute the offset within the top level memory object.
145 RegionOffset getAsOffset() const;
146
147 /// Get a string representation of a region for debug use.
148 std::string getString() const;
149
150 virtual void dumpToStream(raw_ostream &os) const;
151
152 void dump() const;
153
154 /// Returns true if this region can be printed in a user-friendly way.
155 virtual bool canPrintPretty() const;
156
157 /// Print the region for use in diagnostics.
158 virtual void printPretty(raw_ostream &os) const;
159
160 /// Returns true if this region's textual representation can be used
161 /// as part of a larger expression.
162 virtual bool canPrintPrettyAsExpr() const;
163
164 /// Print the region as expression.
165 ///
166 /// When this region represents a subexpression, the method is for printing
167 /// an expression containing it.
168 virtual void printPrettyAsExpr(raw_ostream &os) const;
169
getKind()170 Kind getKind() const { return kind; }
171
172 template<typename RegionTy> const RegionTy* getAs() const;
173
isBoundable()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.
199 class MemSpaceRegion : public MemRegion {
200 protected:
201 MemRegionManager *Mgr;
202
MemSpaceRegion(MemRegionManager * mgr,Kind k)203 MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) {
204 assert(classof(this));
205 assert(mgr);
206 }
207
getMemRegionManager()208 MemRegionManager* getMemRegionManager() const override { return Mgr; }
209
210 public:
isBoundable()211 bool isBoundable() const override { return false; }
212
213 void Profile(llvm::FoldingSetNodeID &ID) const override;
214
classof(const MemRegion * R)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.
223 class CodeSpaceRegion : public MemSpaceRegion {
224 friend class MemRegionManager;
225
CodeSpaceRegion(MemRegionManager * mgr)226 CodeSpaceRegion(MemRegionManager *mgr)
227 : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
228
229 public:
230 void dumpToStream(raw_ostream &os) const override;
231
classof(const MemRegion * R)232 static bool classof(const MemRegion *R) {
233 return R->getKind() == CodeSpaceRegionKind;
234 }
235 };
236
237 class GlobalsSpaceRegion : public MemSpaceRegion {
238 virtual void anchor();
239
240 protected:
GlobalsSpaceRegion(MemRegionManager * mgr,Kind k)241 GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) {
242 assert(classof(this));
243 }
244
245 public:
classof(const MemRegion * R)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.
257 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
258 friend class MemRegionManager;
259
260 const CodeTextRegion *CR;
261
StaticGlobalSpaceRegion(MemRegionManager * mgr,const CodeTextRegion * cr)262 StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
263 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
264 assert(cr);
265 }
266
267 public:
268 void Profile(llvm::FoldingSetNodeID &ID) const override;
269
270 void dumpToStream(raw_ostream &os) const override;
271
getCodeRegion()272 const CodeTextRegion *getCodeRegion() const { return CR; }
273
classof(const MemRegion * R)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).
285 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
286 void anchor() override;
287
288 protected:
NonStaticGlobalSpaceRegion(MemRegionManager * mgr,Kind k)289 NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
290 : GlobalsSpaceRegion(mgr, k) {
291 assert(classof(this));
292 }
293
294 public:
classof(const MemRegion * R)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).
304 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
305 friend class MemRegionManager;
306
GlobalSystemSpaceRegion(MemRegionManager * mgr)307 GlobalSystemSpaceRegion(MemRegionManager *mgr)
308 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
309
310 public:
311 void dumpToStream(raw_ostream &os) const override;
312
classof(const MemRegion * R)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.
323 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
324 friend class MemRegionManager;
325
GlobalImmutableSpaceRegion(MemRegionManager * mgr)326 GlobalImmutableSpaceRegion(MemRegionManager *mgr)
327 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
328
329 public:
330 void dumpToStream(raw_ostream &os) const override;
331
classof(const MemRegion * R)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.
340 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
341 friend class MemRegionManager;
342
GlobalInternalSpaceRegion(MemRegionManager * mgr)343 GlobalInternalSpaceRegion(MemRegionManager *mgr)
344 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
345
346 public:
347 void dumpToStream(raw_ostream &os) const override;
348
classof(const MemRegion * R)349 static bool classof(const MemRegion *R) {
350 return R->getKind() == GlobalInternalSpaceRegionKind;
351 }
352 };
353
354 class HeapSpaceRegion : public MemSpaceRegion {
355 friend class MemRegionManager;
356
HeapSpaceRegion(MemRegionManager * mgr)357 HeapSpaceRegion(MemRegionManager *mgr)
358 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
359
360 public:
361 void dumpToStream(raw_ostream &os) const override;
362
classof(const MemRegion * R)363 static bool classof(const MemRegion *R) {
364 return R->getKind() == HeapSpaceRegionKind;
365 }
366 };
367
368 class UnknownSpaceRegion : public MemSpaceRegion {
369 friend class MemRegionManager;
370
UnknownSpaceRegion(MemRegionManager * mgr)371 UnknownSpaceRegion(MemRegionManager *mgr)
372 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
373
374 public:
375 void dumpToStream(raw_ostream &os) const override;
376
classof(const MemRegion * R)377 static bool classof(const MemRegion *R) {
378 return R->getKind() == UnknownSpaceRegionKind;
379 }
380 };
381
382 class StackSpaceRegion : public MemSpaceRegion {
383 virtual void anchor();
384
385 const StackFrameContext *SFC;
386
387 protected:
StackSpaceRegion(MemRegionManager * mgr,Kind k,const StackFrameContext * sfc)388 StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
389 : MemSpaceRegion(mgr, k), SFC(sfc) {
390 assert(classof(this));
391 assert(sfc);
392 }
393
394 public:
getStackFrame()395 const StackFrameContext *getStackFrame() const { return SFC; }
396
397 void Profile(llvm::FoldingSetNodeID &ID) const override;
398
classof(const MemRegion * R)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
405 class StackLocalsSpaceRegion : public StackSpaceRegion {
406 friend class MemRegionManager;
407
StackLocalsSpaceRegion(MemRegionManager * mgr,const StackFrameContext * sfc)408 StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
409 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
410
411 public:
412 void dumpToStream(raw_ostream &os) const override;
413
classof(const MemRegion * R)414 static bool classof(const MemRegion *R) {
415 return R->getKind() == StackLocalsSpaceRegionKind;
416 }
417 };
418
419 class StackArgumentsSpaceRegion : public StackSpaceRegion {
420 private:
421 friend class MemRegionManager;
422
StackArgumentsSpaceRegion(MemRegionManager * mgr,const StackFrameContext * sfc)423 StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
424 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
425
426 public:
427 void dumpToStream(raw_ostream &os) const override;
428
classof(const MemRegion * R)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.
436 class SubRegion : public MemRegion {
437 virtual void anchor();
438
439 protected:
440 const MemRegion* superRegion;
441
SubRegion(const MemRegion * sReg,Kind k)442 SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
443 assert(classof(this));
444 assert(sReg);
445 }
446
447 public:
getSuperRegion()448 const MemRegion* getSuperRegion() const {
449 return superRegion;
450 }
451
452 /// getExtent - Returns the size of the region in bytes.
getExtent(SValBuilder & svalBuilder)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
classof(const MemRegion * R)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'.
472 class 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
AllocaRegion(const Expr * ex,unsigned cnt,const MemSpaceRegion * superRegion)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
489 public:
getExpr()490 const Expr *getExpr() const { return Ex; }
491
isBoundable()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
classof(const MemRegion * R)500 static bool classof(const MemRegion* R) {
501 return R->getKind() == AllocaRegionKind;
502 }
503 };
504
505 /// TypedRegion - An abstract class representing regions that are typed.
506 class TypedRegion : public SubRegion {
507 void anchor() override;
508
509 protected:
TypedRegion(const MemRegion * sReg,Kind k)510 TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
511 assert(classof(this));
512 }
513
514 public:
515 virtual QualType getLocationType() const = 0;
516
getDesugaredLocationType(ASTContext & Context)517 QualType getDesugaredLocationType(ASTContext &Context) const {
518 return getLocationType().getDesugaredType(Context);
519 }
520
isBoundable()521 bool isBoundable() const override { return true; }
522
classof(const MemRegion * R)523 static bool classof(const MemRegion* R) {
524 unsigned k = R->getKind();
525 return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
526 }
527 };
528
529 /// TypedValueRegion - An abstract class representing regions having a typed value.
530 class TypedValueRegion : public TypedRegion {
531 void anchor() override;
532
533 protected:
TypedValueRegion(const MemRegion * sReg,Kind k)534 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
535 assert(classof(this));
536 }
537
538 public:
539 virtual QualType getValueType() const = 0;
540
getLocationType()541 QualType getLocationType() const override {
542 // FIXME: We can possibly optimize this later to cache this value.
543 QualType T = getValueType();
544 ASTContext &ctx = getContext();
545 if (T->getAs<ObjCObjectType>())
546 return ctx.getObjCObjectPointerType(T);
547 return ctx.getPointerType(getValueType());
548 }
549
getDesugaredValueType(ASTContext & Context)550 QualType getDesugaredValueType(ASTContext &Context) const {
551 QualType T = getValueType();
552 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
553 }
554
555 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
556
classof(const MemRegion * R)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
563 class CodeTextRegion : public TypedRegion {
564 void anchor() override;
565
566 protected:
CodeTextRegion(const MemSpaceRegion * sreg,Kind k)567 CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
568 assert(classof(this));
569 }
570
571 public:
isBoundable()572 bool isBoundable() const override { return false; }
573
classof(const MemRegion * R)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.
581 class FunctionCodeRegion : public CodeTextRegion {
582 friend class MemRegionManager;
583
584 const NamedDecl *FD;
585
FunctionCodeRegion(const NamedDecl * fd,const CodeSpaceRegion * sreg)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
594 public:
getLocationType()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
getDecl()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
classof(const MemRegion * R)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.
628 class BlockCodeRegion : public CodeTextRegion {
629 friend class MemRegionManager;
630
631 const BlockDecl *BD;
632 AnalysisDeclContext *AC;
633 CanQualType locTy;
634
BlockCodeRegion(const BlockDecl * bd,CanQualType lTy,AnalysisDeclContext * ac,const CodeSpaceRegion * sreg)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
647 public:
getLocationType()648 QualType getLocationType() const override {
649 return locTy;
650 }
651
getDecl()652 const BlockDecl *getDecl() const {
653 return BD;
654 }
655
getAnalysisDeclContext()656 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
657
658 void dumpToStream(raw_ostream &os) const override;
659
660 void Profile(llvm::FoldingSetNodeID& ID) const override;
661
classof(const MemRegion * R)662 static bool classof(const MemRegion* R) {
663 return R->getKind() == BlockCodeRegionKind;
664 }
665 };
666
667 /// BlockDataRegion - A region that represents a block instance.
668 /// Blocks are represented with two kinds of regions. BlockCodeRegions
669 /// represent the "code", while BlockDataRegions represent instances of blocks,
670 /// which correspond to "code+data". The distinction is important, because
671 /// like a closure a block captures the values of externally referenced
672 /// variables.
673 class BlockDataRegion : public TypedRegion {
674 friend class MemRegionManager;
675
676 const BlockCodeRegion *BC;
677 const LocationContext *LC; // Can be null
678 unsigned BlockCount;
679 void *ReferencedVars = nullptr;
680 void *OriginalVars = nullptr;
681
BlockDataRegion(const BlockCodeRegion * bc,const LocationContext * lc,unsigned count,const MemSpaceRegion * sreg)682 BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
683 unsigned count, const MemSpaceRegion *sreg)
684 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
685 BlockCount(count) {
686 assert(bc);
687 assert(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
697 public:
getCodeRegion()698 const BlockCodeRegion *getCodeRegion() const { return BC; }
699
getDecl()700 const BlockDecl *getDecl() const { return BC->getDecl(); }
701
getLocationType()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:
referenced_vars_iterator(const MemRegion * const * r,const MemRegion * const * originalR)709 explicit referenced_vars_iterator(const MemRegion * const *r,
710 const MemRegion * const *originalR)
711 : R(r), OriginalR(originalR) {}
712
getCapturedRegion()713 const VarRegion *getCapturedRegion() const {
714 return cast<VarRegion>(*R);
715 }
716
getOriginalRegion()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
classof(const MemRegion * R)749 static bool classof(const MemRegion* R) {
750 return R->getKind() == BlockDataRegionKind;
751 }
752
753 private:
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.
764 class SymbolicRegion : public SubRegion {
765 friend class MemRegionManager;
766
767 const SymbolRef sym;
768
SymbolicRegion(const SymbolRef s,const MemSpaceRegion * sreg)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
778 // populateWorklistFromSymbol() relies on this assertion, and needs to be
779 // updated if more cases are introduced.
780 assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
781 }
782
783 public:
getSymbol()784 SymbolRef getSymbol() const { return sym; }
785
isBoundable()786 bool isBoundable() const override { return true; }
787
788 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
789
790 void Profile(llvm::FoldingSetNodeID& ID) const override;
791
792 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
793 SymbolRef sym,
794 const MemRegion* superRegion);
795
796 void dumpToStream(raw_ostream &os) const override;
797
classof(const MemRegion * R)798 static bool classof(const MemRegion* R) {
799 return R->getKind() == SymbolicRegionKind;
800 }
801 };
802
803 /// StringRegion - Region associated with a StringLiteral.
804 class StringRegion : public TypedValueRegion {
805 friend class MemRegionManager;
806
807 const StringLiteral *Str;
808
StringRegion(const StringLiteral * str,const GlobalInternalSpaceRegion * sreg)809 StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
810 : TypedValueRegion(sreg, StringRegionKind), Str(str) {
811 assert(str);
812 }
813
814 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
815 const StringLiteral *Str,
816 const MemRegion *superRegion);
817
818 public:
getStringLiteral()819 const StringLiteral *getStringLiteral() const { return Str; }
820
getValueType()821 QualType getValueType() const override { return Str->getType(); }
822
823 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
824
isBoundable()825 bool isBoundable() const override { return false; }
826
Profile(llvm::FoldingSetNodeID & ID)827 void Profile(llvm::FoldingSetNodeID& ID) const override {
828 ProfileRegion(ID, Str, superRegion);
829 }
830
831 void dumpToStream(raw_ostream &os) const override;
832
classof(const MemRegion * R)833 static bool classof(const MemRegion* R) {
834 return R->getKind() == StringRegionKind;
835 }
836 };
837
838 /// The region associated with an ObjCStringLiteral.
839 class ObjCStringRegion : public TypedValueRegion {
840 friend class MemRegionManager;
841
842 const ObjCStringLiteral *Str;
843
ObjCStringRegion(const ObjCStringLiteral * str,const GlobalInternalSpaceRegion * sreg)844 ObjCStringRegion(const ObjCStringLiteral *str,
845 const GlobalInternalSpaceRegion *sreg)
846 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
847 assert(str);
848 }
849
850 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
851 const ObjCStringLiteral *Str,
852 const MemRegion *superRegion);
853
854 public:
getObjCStringLiteral()855 const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
856
getValueType()857 QualType getValueType() const override { return Str->getType(); }
858
isBoundable()859 bool isBoundable() const override { return false; }
860
Profile(llvm::FoldingSetNodeID & ID)861 void Profile(llvm::FoldingSetNodeID& ID) const override {
862 ProfileRegion(ID, Str, superRegion);
863 }
864
865 void dumpToStream(raw_ostream &os) const override;
866
classof(const MemRegion * R)867 static bool classof(const MemRegion* R) {
868 return R->getKind() == ObjCStringRegionKind;
869 }
870 };
871
872 /// CompoundLiteralRegion - A memory region representing a compound literal.
873 /// Compound literals are essentially temporaries that are stack allocated
874 /// or in the global constant pool.
875 class CompoundLiteralRegion : public TypedValueRegion {
876 friend class MemRegionManager;
877
878 const CompoundLiteralExpr *CL;
879
CompoundLiteralRegion(const CompoundLiteralExpr * cl,const MemSpaceRegion * sReg)880 CompoundLiteralRegion(const CompoundLiteralExpr *cl,
881 const MemSpaceRegion *sReg)
882 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
883 assert(cl);
884 assert(isa<GlobalInternalSpaceRegion>(sReg) ||
885 isa<StackLocalsSpaceRegion>(sReg));
886 }
887
888 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
889 const CompoundLiteralExpr *CL,
890 const MemRegion* superRegion);
891
892 public:
getValueType()893 QualType getValueType() const override { return CL->getType(); }
894
isBoundable()895 bool isBoundable() const override { return !CL->isFileScope(); }
896
897 void Profile(llvm::FoldingSetNodeID& ID) const override;
898
899 void dumpToStream(raw_ostream &os) const override;
900
getLiteralExpr()901 const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
902
classof(const MemRegion * R)903 static bool classof(const MemRegion* R) {
904 return R->getKind() == CompoundLiteralRegionKind;
905 }
906 };
907
908 class DeclRegion : public TypedValueRegion {
909 protected:
910 const ValueDecl *D;
911
DeclRegion(const ValueDecl * d,const MemRegion * sReg,Kind k)912 DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
913 : TypedValueRegion(sReg, k), D(d) {
914 assert(classof(this));
915 assert(d);
916 }
917
918 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
919 const MemRegion* superRegion, Kind k);
920
921 public:
getDecl()922 const ValueDecl *getDecl() const { return D; }
923 void Profile(llvm::FoldingSetNodeID& ID) const override;
924
classof(const MemRegion * R)925 static bool classof(const MemRegion* R) {
926 unsigned k = R->getKind();
927 return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
928 }
929 };
930
931 class VarRegion : public DeclRegion {
932 friend class MemRegionManager;
933
934 // Constructors and private methods.
VarRegion(const VarDecl * vd,const MemRegion * sReg)935 VarRegion(const VarDecl *vd, const MemRegion *sReg)
936 : DeclRegion(vd, sReg, VarRegionKind) {
937 // VarRegion appears in unknown space when it's a block variable as seen
938 // from a block using it, when this block is analyzed at top-level.
939 // Other block variables appear within block data regions,
940 // which, unlike everything else on this list, are not memory spaces.
941 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
942 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
943 }
944
ProfileRegion(llvm::FoldingSetNodeID & ID,const VarDecl * VD,const MemRegion * superRegion)945 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
946 const MemRegion *superRegion) {
947 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
948 }
949
950 public:
951 void Profile(llvm::FoldingSetNodeID& ID) const override;
952
getDecl()953 const VarDecl *getDecl() const { return cast<VarDecl>(D); }
954
955 const StackFrameContext *getStackFrame() const;
956
getValueType()957 QualType getValueType() const override {
958 // FIXME: We can cache this if needed.
959 return getDecl()->getType();
960 }
961
962 void dumpToStream(raw_ostream &os) const override;
963
964 bool canPrintPrettyAsExpr() const override;
965
966 void printPrettyAsExpr(raw_ostream &os) const override;
967
classof(const MemRegion * R)968 static bool classof(const MemRegion* R) {
969 return R->getKind() == VarRegionKind;
970 }
971 };
972
973 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
974 /// in a call to a C++ method. This region doesn't represent the object
975 /// referred to by 'this', but rather 'this' itself.
976 class CXXThisRegion : public TypedValueRegion {
977 friend class MemRegionManager;
978
CXXThisRegion(const PointerType * thisPointerTy,const StackArgumentsSpaceRegion * sReg)979 CXXThisRegion(const PointerType *thisPointerTy,
980 const StackArgumentsSpaceRegion *sReg)
981 : TypedValueRegion(sReg, CXXThisRegionKind),
982 ThisPointerTy(thisPointerTy) {
983 assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
984 "Invalid region type!");
985 }
986
987 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
988 const PointerType *PT,
989 const MemRegion *sReg);
990
991 public:
992 void Profile(llvm::FoldingSetNodeID &ID) const override;
993
getValueType()994 QualType getValueType() const override {
995 return QualType(ThisPointerTy, 0);
996 }
997
998 void dumpToStream(raw_ostream &os) const override;
999
classof(const MemRegion * R)1000 static bool classof(const MemRegion* R) {
1001 return R->getKind() == CXXThisRegionKind;
1002 }
1003
1004 private:
1005 const PointerType *ThisPointerTy;
1006 };
1007
1008 class FieldRegion : public DeclRegion {
1009 friend class MemRegionManager;
1010
FieldRegion(const FieldDecl * fd,const SubRegion * sReg)1011 FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
1012 : DeclRegion(fd, sReg, FieldRegionKind) {}
1013
ProfileRegion(llvm::FoldingSetNodeID & ID,const FieldDecl * FD,const MemRegion * superRegion)1014 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
1015 const MemRegion* superRegion) {
1016 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
1017 }
1018
1019 public:
getDecl()1020 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
1021
getValueType()1022 QualType getValueType() const override {
1023 // FIXME: We can cache this if needed.
1024 return getDecl()->getType();
1025 }
1026
1027 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
1028
1029 void dumpToStream(raw_ostream &os) const override;
1030
1031 bool canPrintPretty() const override;
1032 void printPretty(raw_ostream &os) const override;
1033 bool canPrintPrettyAsExpr() const override;
1034 void printPrettyAsExpr(raw_ostream &os) const override;
1035
classof(const MemRegion * R)1036 static bool classof(const MemRegion* R) {
1037 return R->getKind() == FieldRegionKind;
1038 }
1039 };
1040
1041 class ObjCIvarRegion : public DeclRegion {
1042 friend class MemRegionManager;
1043
1044 ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1045
1046 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1047 const MemRegion* superRegion);
1048
1049 public:
1050 const ObjCIvarDecl *getDecl() const;
1051 QualType getValueType() const override;
1052
1053 bool canPrintPrettyAsExpr() const override;
1054 void printPrettyAsExpr(raw_ostream &os) const override;
1055
1056 void dumpToStream(raw_ostream &os) const override;
1057
classof(const MemRegion * R)1058 static bool classof(const MemRegion* R) {
1059 return R->getKind() == ObjCIvarRegionKind;
1060 }
1061 };
1062
1063 //===----------------------------------------------------------------------===//
1064 // Auxiliary data classes for use with MemRegions.
1065 //===----------------------------------------------------------------------===//
1066
1067 class RegionRawOffset {
1068 friend class ElementRegion;
1069
1070 const MemRegion *Region;
1071 CharUnits Offset;
1072
1073 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
Region(reg)1074 : Region(reg), Offset(offset) {}
1075
1076 public:
1077 // FIXME: Eventually support symbolic offsets.
getOffset()1078 CharUnits getOffset() const { return Offset; }
getRegion()1079 const MemRegion *getRegion() const { return Region; }
1080
1081 void dumpToStream(raw_ostream &os) const;
1082 void dump() const;
1083 };
1084
1085 /// ElementRegion is used to represent both array elements and casts.
1086 class ElementRegion : public TypedValueRegion {
1087 friend class MemRegionManager;
1088
1089 QualType ElementType;
1090 NonLoc Index;
1091
ElementRegion(QualType elementType,NonLoc Idx,const SubRegion * sReg)1092 ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1093 : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1094 Index(Idx) {
1095 assert((!Idx.getAs<nonloc::ConcreteInt>() ||
1096 Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
1097 "The index must be signed");
1098 assert(!elementType.isNull() && !elementType->isVoidType() &&
1099 "Invalid region type!");
1100 }
1101
1102 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1103 SVal Idx, const MemRegion* superRegion);
1104
1105 public:
getIndex()1106 NonLoc getIndex() const { return Index; }
1107
getValueType()1108 QualType getValueType() const override { return ElementType; }
1109
getElementType()1110 QualType getElementType() const { return ElementType; }
1111
1112 /// Compute the offset within the array. The array might also be a subobject.
1113 RegionRawOffset getAsArrayOffset() const;
1114
1115 void dumpToStream(raw_ostream &os) const override;
1116
1117 void Profile(llvm::FoldingSetNodeID& ID) const override;
1118
classof(const MemRegion * R)1119 static bool classof(const MemRegion* R) {
1120 return R->getKind() == ElementRegionKind;
1121 }
1122 };
1123
1124 // C++ temporary object associated with an expression.
1125 class CXXTempObjectRegion : public TypedValueRegion {
1126 friend class MemRegionManager;
1127
1128 Expr const *Ex;
1129
CXXTempObjectRegion(Expr const * E,MemSpaceRegion const * sReg)1130 CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1131 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1132 assert(E);
1133 assert(isa<StackLocalsSpaceRegion>(sReg) ||
1134 isa<GlobalInternalSpaceRegion>(sReg));
1135 }
1136
1137 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1138 Expr const *E, const MemRegion *sReg);
1139
1140 public:
getExpr()1141 const Expr *getExpr() const { return Ex; }
1142
getValueType()1143 QualType getValueType() const override { return Ex->getType(); }
1144
1145 void dumpToStream(raw_ostream &os) const override;
1146
1147 void Profile(llvm::FoldingSetNodeID &ID) const override;
1148
classof(const MemRegion * R)1149 static bool classof(const MemRegion* R) {
1150 return R->getKind() == CXXTempObjectRegionKind;
1151 }
1152 };
1153
1154 // CXXBaseObjectRegion represents a base object within a C++ object. It is
1155 // identified by the base class declaration and the region of its parent object.
1156 class CXXBaseObjectRegion : public TypedValueRegion {
1157 friend class MemRegionManager;
1158
1159 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1160
CXXBaseObjectRegion(const CXXRecordDecl * RD,bool IsVirtual,const SubRegion * SReg)1161 CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1162 const SubRegion *SReg)
1163 : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1164 assert(RD);
1165 }
1166
1167 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1168 bool IsVirtual, const MemRegion *SReg);
1169
1170 public:
getDecl()1171 const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
isVirtual()1172 bool isVirtual() const { return Data.getInt(); }
1173
1174 QualType getValueType() const override;
1175
1176 void dumpToStream(raw_ostream &os) const override;
1177
1178 void Profile(llvm::FoldingSetNodeID &ID) const override;
1179
1180 bool canPrintPrettyAsExpr() const override;
1181
1182 void printPrettyAsExpr(raw_ostream &os) const override;
1183
classof(const MemRegion * region)1184 static bool classof(const MemRegion *region) {
1185 return region->getKind() == CXXBaseObjectRegionKind;
1186 }
1187 };
1188
1189 // CXXDerivedObjectRegion represents a derived-class object that surrounds
1190 // a C++ object. It is identified by the derived class declaration and the
1191 // region of its parent object. It is a bit counter-intuitive (but not otherwise
1192 // unseen) that this region represents a larger segment of memory that its
1193 // super-region.
1194 class CXXDerivedObjectRegion : public TypedValueRegion {
1195 friend class MemRegionManager;
1196
1197 const CXXRecordDecl *DerivedD;
1198
CXXDerivedObjectRegion(const CXXRecordDecl * DerivedD,const SubRegion * SReg)1199 CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1200 : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1201 assert(DerivedD);
1202 // In case of a concrete region, it should always be possible to model
1203 // the base-to-derived cast by undoing a previous derived-to-base cast,
1204 // otherwise the cast is most likely ill-formed.
1205 assert(SReg->getSymbolicBase() &&
1206 "Should have unwrapped a base region instead!");
1207 }
1208
1209 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1210 const MemRegion *SReg);
1211
1212 public:
getDecl()1213 const CXXRecordDecl *getDecl() const { return DerivedD; }
1214
1215 QualType getValueType() const override;
1216
1217 void dumpToStream(raw_ostream &os) const override;
1218
1219 void Profile(llvm::FoldingSetNodeID &ID) const override;
1220
1221 bool canPrintPrettyAsExpr() const override;
1222
1223 void printPrettyAsExpr(raw_ostream &os) const override;
1224
classof(const MemRegion * region)1225 static bool classof(const MemRegion *region) {
1226 return region->getKind() == CXXDerivedObjectRegionKind;
1227 }
1228 };
1229
1230 template<typename RegionTy>
getAs()1231 const RegionTy* MemRegion::getAs() const {
1232 if (const auto *RT = dyn_cast<RegionTy>(this))
1233 return RT;
1234
1235 return nullptr;
1236 }
1237
1238 //===----------------------------------------------------------------------===//
1239 // MemRegionManager - Factory object for creating regions.
1240 //===----------------------------------------------------------------------===//
1241
1242 class MemRegionManager {
1243 ASTContext &C;
1244 llvm::BumpPtrAllocator& A;
1245 llvm::FoldingSet<MemRegion> Regions;
1246
1247 GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1248 GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1249 GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1250
1251 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1252 StackLocalsSpaceRegions;
1253 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1254 StackArgumentsSpaceRegions;
1255 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1256 StaticsGlobalSpaceRegions;
1257
1258 HeapSpaceRegion *heap = nullptr;
1259 UnknownSpaceRegion *unknown = nullptr;
1260 CodeSpaceRegion *code = nullptr;
1261
1262 public:
MemRegionManager(ASTContext & c,llvm::BumpPtrAllocator & a)1263 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {}
1264 ~MemRegionManager();
1265
getContext()1266 ASTContext &getContext() { return C; }
1267
getAllocator()1268 llvm::BumpPtrAllocator &getAllocator() { return A; }
1269
1270 /// getStackLocalsRegion - Retrieve the memory region associated with the
1271 /// specified stack frame.
1272 const StackLocalsSpaceRegion *
1273 getStackLocalsRegion(const StackFrameContext *STC);
1274
1275 /// getStackArgumentsRegion - Retrieve the memory region associated with
1276 /// function/method arguments of the specified stack frame.
1277 const StackArgumentsSpaceRegion *
1278 getStackArgumentsRegion(const StackFrameContext *STC);
1279
1280 /// getGlobalsRegion - Retrieve the memory region associated with
1281 /// global variables.
1282 const GlobalsSpaceRegion *getGlobalsRegion(
1283 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1284 const CodeTextRegion *R = nullptr);
1285
1286 /// getHeapRegion - Retrieve the memory region associated with the
1287 /// generic "heap".
1288 const HeapSpaceRegion *getHeapRegion();
1289
1290 /// getUnknownRegion - Retrieve the memory region associated with unknown
1291 /// memory space.
1292 const UnknownSpaceRegion *getUnknownRegion();
1293
1294 const CodeSpaceRegion *getCodeRegion();
1295
1296 /// getAllocaRegion - Retrieve a region associated with a call to alloca().
1297 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1298 const LocationContext *LC);
1299
1300 /// getCompoundLiteralRegion - Retrieve the region associated with a
1301 /// given CompoundLiteral.
1302 const CompoundLiteralRegion*
1303 getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1304 const LocationContext *LC);
1305
1306 /// getCXXThisRegion - Retrieve the [artificial] region associated with the
1307 /// parameter 'this'.
1308 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1309 const LocationContext *LC);
1310
1311 /// Retrieve or create a "symbolic" memory region.
1312 const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
1313
1314 /// Return a unique symbolic region belonging to heap memory space.
1315 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1316
1317 const StringRegion *getStringRegion(const StringLiteral *Str);
1318
1319 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1320
1321 /// getVarRegion - Retrieve or create the memory region associated with
1322 /// a specified VarDecl and LocationContext.
1323 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
1324
1325 /// getVarRegion - Retrieve or create the memory region associated with
1326 /// a specified VarDecl and super region.
1327 const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
1328
1329 /// getElementRegion - Retrieve the memory region associated with the
1330 /// associated element type, index, and super region.
1331 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1332 const SubRegion *superRegion,
1333 ASTContext &Ctx);
1334
getElementRegionWithSuper(const ElementRegion * ER,const SubRegion * superRegion)1335 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1336 const SubRegion *superRegion) {
1337 return getElementRegion(ER->getElementType(), ER->getIndex(),
1338 superRegion, ER->getContext());
1339 }
1340
1341 /// getFieldRegion - Retrieve or create the memory region associated with
1342 /// a specified FieldDecl. 'superRegion' corresponds to the containing
1343 /// memory region (which typically represents the memory representing
1344 /// a structure or class).
1345 const FieldRegion *getFieldRegion(const FieldDecl *fd,
1346 const SubRegion* superRegion);
1347
getFieldRegionWithSuper(const FieldRegion * FR,const SubRegion * superRegion)1348 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1349 const SubRegion *superRegion) {
1350 return getFieldRegion(FR->getDecl(), superRegion);
1351 }
1352
1353 /// getObjCIvarRegion - Retrieve or create the memory region associated with
1354 /// a specified Objective-c instance variable. 'superRegion' corresponds
1355 /// to the containing region (which typically represents the Objective-C
1356 /// object).
1357 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1358 const SubRegion* superRegion);
1359
1360 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1361 LocationContext const *LC);
1362
1363 /// Create a CXXBaseObjectRegion with the given base class for region
1364 /// \p Super.
1365 ///
1366 /// The type of \p Super is assumed be a class deriving from \p BaseClass.
1367 const CXXBaseObjectRegion *
1368 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1369 bool IsVirtual);
1370
1371 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
1372 /// super region.
1373 const CXXBaseObjectRegion *
getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion * baseReg,const SubRegion * superRegion)1374 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1375 const SubRegion *superRegion) {
1376 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1377 baseReg->isVirtual());
1378 }
1379
1380 /// Create a CXXDerivedObjectRegion with the given derived class for region
1381 /// \p Super. This should not be used for casting an existing
1382 /// CXXBaseObjectRegion back to the derived type; instead, CXXBaseObjectRegion
1383 /// should be removed.
1384 const CXXDerivedObjectRegion *
1385 getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1386 const SubRegion *Super);
1387
1388 const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1389 const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1390 CanQualType locTy,
1391 AnalysisDeclContext *AC);
1392
1393 /// getBlockDataRegion - Get the memory region associated with an instance
1394 /// of a block. Unlike many other MemRegions, the LocationContext*
1395 /// argument is allowed to be NULL for cases where we have no known
1396 /// context.
1397 const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1398 const LocationContext *lc,
1399 unsigned blockCount);
1400
1401 /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
1402 /// by static references. This differs from getCXXTempObjectRegion in the
1403 /// super-region used.
1404 const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
1405
1406 private:
1407 template <typename RegionTy, typename SuperTy,
1408 typename Arg1Ty>
1409 RegionTy* getSubRegion(const Arg1Ty arg1,
1410 const SuperTy* superRegion);
1411
1412 template <typename RegionTy, typename SuperTy,
1413 typename Arg1Ty, typename Arg2Ty>
1414 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1415 const SuperTy* superRegion);
1416
1417 template <typename RegionTy, typename SuperTy,
1418 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1419 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1420 const Arg3Ty arg3,
1421 const SuperTy* superRegion);
1422
1423 template <typename REG>
1424 const REG* LazyAllocate(REG*& region);
1425
1426 template <typename REG, typename ARG>
1427 const REG* LazyAllocate(REG*& region, ARG a);
1428 };
1429
1430 //===----------------------------------------------------------------------===//
1431 // Out-of-line member definitions.
1432 //===----------------------------------------------------------------------===//
1433
getContext()1434 inline ASTContext &MemRegion::getContext() const {
1435 return getMemRegionManager()->getContext();
1436 }
1437
1438 //===----------------------------------------------------------------------===//
1439 // Means for storing region/symbol handling traits.
1440 //===----------------------------------------------------------------------===//
1441
1442 /// Information about invalidation for a particular region/symbol.
1443 class RegionAndSymbolInvalidationTraits {
1444 using StorageTypeForKinds = unsigned char;
1445
1446 llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1447 llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1448
1449 using const_region_iterator =
1450 llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1451 using const_symbol_iterator =
1452 llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1453
1454 public:
1455 /// Describes different invalidation traits.
1456 enum InvalidationKinds {
1457 /// Tells that a region's contents is not changed.
1458 TK_PreserveContents = 0x1,
1459
1460 /// Suppress pointer-escaping of a region.
1461 TK_SuppressEscape = 0x2,
1462
1463 // Do not invalidate super region.
1464 TK_DoNotInvalidateSuperRegion = 0x4,
1465
1466 /// When applied to a MemSpaceRegion, indicates the entire memory space
1467 /// should be invalidated.
1468 TK_EntireMemSpace = 0x8
1469
1470 // Do not forget to extend StorageTypeForKinds if number of traits exceed
1471 // the number of bits StorageTypeForKinds can store.
1472 };
1473
1474 void setTrait(SymbolRef Sym, InvalidationKinds IK);
1475 void setTrait(const MemRegion *MR, InvalidationKinds IK);
1476 bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1477 bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1478 };
1479
1480 //===----------------------------------------------------------------------===//
1481 // Pretty-printing regions.
1482 //===----------------------------------------------------------------------===//
1483 inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1484 R->dumpToStream(os);
1485 return os;
1486 }
1487
1488 } // namespace ento
1489
1490 } // namespace clang
1491
1492 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
1493