File indexing completed on 2026-05-10 08:37:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
0016 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
0017
0018 #include "clang/AST/ASTContext.h"
0019 #include "clang/AST/CharUnits.h"
0020 #include "clang/AST/Decl.h"
0021 #include "clang/AST/DeclObjC.h"
0022 #include "clang/AST/DeclarationName.h"
0023 #include "clang/AST/Expr.h"
0024 #include "clang/AST/ExprObjC.h"
0025 #include "clang/AST/Type.h"
0026 #include "clang/Analysis/AnalysisDeclContext.h"
0027 #include "clang/Basic/LLVM.h"
0028 #include "clang/Basic/SourceLocation.h"
0029 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0030 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
0031 #include "llvm/ADT/DenseMap.h"
0032 #include "llvm/ADT/FoldingSet.h"
0033 #include "llvm/ADT/PointerIntPair.h"
0034 #include "llvm/ADT/iterator_range.h"
0035 #include "llvm/Support/Allocator.h"
0036 #include "llvm/Support/Casting.h"
0037 #include "llvm/Support/ErrorHandling.h"
0038 #include <cassert>
0039 #include <cstdint>
0040 #include <limits>
0041 #include <optional>
0042 #include <string>
0043 #include <utility>
0044
0045 namespace clang {
0046
0047 class AnalysisDeclContext;
0048 class CXXRecordDecl;
0049 class Decl;
0050 class LocationContext;
0051 class StackFrameContext;
0052
0053 namespace ento {
0054
0055 class CodeTextRegion;
0056 class MemRegion;
0057 class MemRegionManager;
0058 class MemSpaceRegion;
0059 class SValBuilder;
0060 class SymbolicRegion;
0061 class VarRegion;
0062
0063
0064 class RegionOffset {
0065
0066 const MemRegion *R = nullptr;
0067
0068
0069 int64_t Offset;
0070
0071 public:
0072
0073
0074 static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
0075
0076 RegionOffset() = default;
0077 RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
0078
0079
0080 const MemRegion *getRegion() const { return R; }
0081
0082 bool hasSymbolicOffset() const { return Offset == Symbolic; }
0083
0084 int64_t getOffset() const {
0085 assert(!hasSymbolicOffset());
0086 return Offset;
0087 }
0088
0089 bool isValid() const { return R; }
0090 };
0091
0092
0093
0094
0095
0096
0097 class MemRegion : public llvm::FoldingSetNode {
0098 public:
0099 enum Kind {
0100 #define REGION(Id, Parent) Id ## Kind,
0101 #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
0102 #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
0103 #undef REGION
0104 #undef REGION_RANGE
0105 };
0106
0107 private:
0108 const Kind kind;
0109 mutable std::optional<RegionOffset> cachedOffset;
0110
0111 protected:
0112 MemRegion(Kind k) : kind(k) {}
0113 virtual ~MemRegion();
0114
0115 public:
0116 ASTContext &getContext() const;
0117
0118 virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
0119
0120 virtual MemRegionManager &getMemRegionManager() const = 0;
0121
0122 LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const;
0123
0124 LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const;
0125
0126
0127
0128 LLVM_ATTRIBUTE_RETURNS_NONNULL
0129 const MemRegion *getMostDerivedObjectRegion() const;
0130
0131
0132
0133 virtual bool isSubRegionOf(const MemRegion *R) const;
0134
0135 LLVM_ATTRIBUTE_RETURNS_NONNULL
0136 const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
0137
0138
0139
0140
0141 const SymbolicRegion *getSymbolicBase() const;
0142
0143 bool hasStackStorage() const;
0144
0145 bool hasStackNonParametersStorage() const;
0146
0147 bool hasStackParametersStorage() const;
0148
0149
0150 RegionOffset getAsOffset() const;
0151
0152
0153 std::string getString() const;
0154
0155 virtual void dumpToStream(raw_ostream &os) const;
0156
0157 void dump() const;
0158
0159
0160 virtual bool canPrintPretty() const;
0161
0162
0163 virtual void printPretty(raw_ostream &os) const;
0164
0165
0166
0167 virtual bool canPrintPrettyAsExpr() const;
0168
0169
0170
0171
0172
0173 virtual void printPrettyAsExpr(raw_ostream &os) const;
0174
0175 Kind getKind() const { return kind; }
0176
0177 StringRef getKindStr() const;
0178
0179 template<typename RegionTy> const RegionTy* getAs() const;
0180 template <typename RegionTy>
0181 LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const;
0182
0183 virtual bool isBoundable() const { return false; }
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 std::string getDescriptiveName(bool UseQuotes = true) const;
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 SourceRange sourceRange() const;
0204 };
0205
0206
0207
0208 class MemSpaceRegion : public MemRegion {
0209 protected:
0210 MemRegionManager &Mgr;
0211
0212 MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
0213 assert(classof(this));
0214 }
0215
0216 MemRegionManager &getMemRegionManager() const override { return Mgr; }
0217
0218 public:
0219 bool isBoundable() const override { return false; }
0220
0221 void Profile(llvm::FoldingSetNodeID &ID) const override;
0222
0223 static bool classof(const MemRegion *R) {
0224 Kind k = R->getKind();
0225 return k >= BEGIN_MEMSPACES && k <= END_MEMSPACES;
0226 }
0227 };
0228
0229
0230
0231 class CodeSpaceRegion : public MemSpaceRegion {
0232 friend class MemRegionManager;
0233
0234 CodeSpaceRegion(MemRegionManager &mgr)
0235 : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
0236
0237 public:
0238 void dumpToStream(raw_ostream &os) const override;
0239
0240 static bool classof(const MemRegion *R) {
0241 return R->getKind() == CodeSpaceRegionKind;
0242 }
0243 };
0244
0245 class GlobalsSpaceRegion : public MemSpaceRegion {
0246 virtual void anchor();
0247
0248 protected:
0249 GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
0250 assert(classof(this));
0251 }
0252
0253 public:
0254 static bool classof(const MemRegion *R) {
0255 Kind k = R->getKind();
0256 return k >= BEGIN_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
0257 }
0258 };
0259
0260
0261
0262
0263
0264
0265 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
0266 friend class MemRegionManager;
0267
0268 const CodeTextRegion *CR;
0269
0270 StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr)
0271 : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
0272 assert(cr);
0273 }
0274
0275 public:
0276 void Profile(llvm::FoldingSetNodeID &ID) const override;
0277
0278 void dumpToStream(raw_ostream &os) const override;
0279
0280 LLVM_ATTRIBUTE_RETURNS_NONNULL
0281 const CodeTextRegion *getCodeRegion() const { return CR; }
0282
0283 static bool classof(const MemRegion *R) {
0284 return R->getKind() == StaticGlobalSpaceRegionKind;
0285 }
0286 };
0287
0288
0289
0290
0291
0292
0293
0294 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
0295 void anchor() override;
0296
0297 protected:
0298 NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
0299 : GlobalsSpaceRegion(mgr, k) {
0300 assert(classof(this));
0301 }
0302
0303 public:
0304 static bool classof(const MemRegion *R) {
0305 Kind k = R->getKind();
0306 return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
0307 k <= END_NON_STATIC_GLOBAL_MEMSPACES;
0308 }
0309 };
0310
0311
0312
0313 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
0314 friend class MemRegionManager;
0315
0316 GlobalSystemSpaceRegion(MemRegionManager &mgr)
0317 : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
0318
0319 public:
0320 void dumpToStream(raw_ostream &os) const override;
0321
0322 static bool classof(const MemRegion *R) {
0323 return R->getKind() == GlobalSystemSpaceRegionKind;
0324 }
0325 };
0326
0327
0328
0329
0330
0331
0332 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
0333 friend class MemRegionManager;
0334
0335 GlobalImmutableSpaceRegion(MemRegionManager &mgr)
0336 : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
0337
0338 public:
0339 void dumpToStream(raw_ostream &os) const override;
0340
0341 static bool classof(const MemRegion *R) {
0342 return R->getKind() == GlobalImmutableSpaceRegionKind;
0343 }
0344 };
0345
0346
0347
0348
0349 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
0350 friend class MemRegionManager;
0351
0352 GlobalInternalSpaceRegion(MemRegionManager &mgr)
0353 : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
0354
0355 public:
0356 void dumpToStream(raw_ostream &os) const override;
0357
0358 static bool classof(const MemRegion *R) {
0359 return R->getKind() == GlobalInternalSpaceRegionKind;
0360 }
0361 };
0362
0363 class HeapSpaceRegion : public MemSpaceRegion {
0364 friend class MemRegionManager;
0365
0366 HeapSpaceRegion(MemRegionManager &mgr)
0367 : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
0368
0369 public:
0370 void dumpToStream(raw_ostream &os) const override;
0371
0372 static bool classof(const MemRegion *R) {
0373 return R->getKind() == HeapSpaceRegionKind;
0374 }
0375 };
0376
0377 class UnknownSpaceRegion : public MemSpaceRegion {
0378 friend class MemRegionManager;
0379
0380 UnknownSpaceRegion(MemRegionManager &mgr)
0381 : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
0382
0383 public:
0384 void dumpToStream(raw_ostream &os) const override;
0385
0386 static bool classof(const MemRegion *R) {
0387 return R->getKind() == UnknownSpaceRegionKind;
0388 }
0389 };
0390
0391 class StackSpaceRegion : public MemSpaceRegion {
0392 virtual void anchor();
0393
0394 const StackFrameContext *SFC;
0395
0396 protected:
0397 StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
0398 : MemSpaceRegion(mgr, k), SFC(sfc) {
0399 assert(classof(this));
0400 assert(sfc);
0401 }
0402
0403 public:
0404 LLVM_ATTRIBUTE_RETURNS_NONNULL
0405 const StackFrameContext *getStackFrame() const { return SFC; }
0406
0407 void Profile(llvm::FoldingSetNodeID &ID) const override;
0408
0409 static bool classof(const MemRegion *R) {
0410 Kind k = R->getKind();
0411 return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
0412 }
0413 };
0414
0415 class StackLocalsSpaceRegion : public StackSpaceRegion {
0416 friend class MemRegionManager;
0417
0418 StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
0419 : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
0420
0421 public:
0422 void dumpToStream(raw_ostream &os) const override;
0423
0424 static bool classof(const MemRegion *R) {
0425 return R->getKind() == StackLocalsSpaceRegionKind;
0426 }
0427 };
0428
0429 class StackArgumentsSpaceRegion : public StackSpaceRegion {
0430 private:
0431 friend class MemRegionManager;
0432
0433 StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
0434 : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
0435
0436 public:
0437 void dumpToStream(raw_ostream &os) const override;
0438
0439 static bool classof(const MemRegion *R) {
0440 return R->getKind() == StackArgumentsSpaceRegionKind;
0441 }
0442 };
0443
0444
0445
0446 class SubRegion : public MemRegion {
0447 virtual void anchor();
0448
0449 protected:
0450 const MemRegion* superRegion;
0451
0452 SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
0453 assert(classof(this));
0454 assert(sReg);
0455 }
0456
0457 public:
0458 LLVM_ATTRIBUTE_RETURNS_NONNULL
0459 const MemRegion* getSuperRegion() const {
0460 return superRegion;
0461 }
0462
0463 MemRegionManager &getMemRegionManager() const override;
0464
0465 bool isSubRegionOf(const MemRegion* R) const override;
0466
0467 static bool classof(const MemRegion* R) {
0468 return R->getKind() > END_MEMSPACES;
0469 }
0470 };
0471
0472
0473
0474
0475
0476
0477
0478 class AllocaRegion : public SubRegion {
0479 friend class MemRegionManager;
0480
0481
0482
0483 unsigned Cnt;
0484
0485 const Expr *Ex;
0486
0487 AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
0488 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
0489 assert(Ex);
0490 }
0491
0492 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
0493 unsigned Cnt, const MemRegion *superRegion);
0494
0495 public:
0496 LLVM_ATTRIBUTE_RETURNS_NONNULL
0497 const Expr *getExpr() const { return Ex; }
0498
0499 bool isBoundable() const override { return true; }
0500
0501 void Profile(llvm::FoldingSetNodeID& ID) const override;
0502
0503 void dumpToStream(raw_ostream &os) const override;
0504
0505 static bool classof(const MemRegion* R) {
0506 return R->getKind() == AllocaRegionKind;
0507 }
0508 };
0509
0510
0511 class TypedRegion : public SubRegion {
0512 void anchor() override;
0513
0514 protected:
0515 TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
0516 assert(classof(this));
0517 }
0518
0519 public:
0520 virtual QualType getLocationType() const = 0;
0521
0522 QualType getDesugaredLocationType(ASTContext &Context) const {
0523 return getLocationType().getDesugaredType(Context);
0524 }
0525
0526 bool isBoundable() const override { return true; }
0527
0528 static bool classof(const MemRegion* R) {
0529 unsigned k = R->getKind();
0530 return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS;
0531 }
0532 };
0533
0534
0535 class TypedValueRegion : public TypedRegion {
0536 void anchor() override;
0537
0538 protected:
0539 TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
0540 assert(classof(this));
0541 }
0542
0543 public:
0544 virtual QualType getValueType() const = 0;
0545
0546 QualType getLocationType() const override {
0547
0548 QualType T = getValueType();
0549 ASTContext &ctx = getContext();
0550 if (T->getAs<ObjCObjectType>())
0551 return ctx.getObjCObjectPointerType(T);
0552 return ctx.getPointerType(getValueType());
0553 }
0554
0555 QualType getDesugaredValueType(ASTContext &Context) const {
0556 QualType T = getValueType();
0557 return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
0558 }
0559
0560 static bool classof(const MemRegion* R) {
0561 unsigned k = R->getKind();
0562 return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
0563 }
0564 };
0565
0566 class CodeTextRegion : public TypedRegion {
0567 void anchor() override;
0568
0569 protected:
0570 CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
0571 assert(classof(this));
0572 }
0573
0574 public:
0575 bool isBoundable() const override { return false; }
0576
0577 static bool classof(const MemRegion* R) {
0578 Kind k = R->getKind();
0579 return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS;
0580 }
0581 };
0582
0583
0584 class FunctionCodeRegion : public CodeTextRegion {
0585 friend class MemRegionManager;
0586
0587 const NamedDecl *FD;
0588
0589 FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
0590 : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
0591 assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
0592 }
0593
0594 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
0595 const MemRegion*);
0596
0597 public:
0598 QualType getLocationType() const override {
0599 const ASTContext &Ctx = getContext();
0600 if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
0601 return Ctx.getPointerType(D->getType());
0602 }
0603
0604 assert(isa<ObjCMethodDecl>(FD));
0605 assert(false && "Getting the type of ObjCMethod is not supported yet");
0606
0607
0608
0609 return {};
0610 }
0611
0612 const NamedDecl *getDecl() const {
0613 return FD;
0614 }
0615
0616 void dumpToStream(raw_ostream &os) const override;
0617
0618 void Profile(llvm::FoldingSetNodeID& ID) const override;
0619
0620 static bool classof(const MemRegion* R) {
0621 return R->getKind() == FunctionCodeRegionKind;
0622 }
0623 };
0624
0625
0626
0627
0628
0629
0630
0631 class BlockCodeRegion : public CodeTextRegion {
0632 friend class MemRegionManager;
0633
0634 const BlockDecl *BD;
0635 AnalysisDeclContext *AC;
0636 CanQualType locTy;
0637
0638 BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
0639 AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
0640 : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
0641 assert(bd);
0642 assert(ac);
0643 assert(lTy->getTypePtr()->isBlockPointerType());
0644 }
0645
0646 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
0647 CanQualType, const AnalysisDeclContext*,
0648 const MemRegion*);
0649
0650 public:
0651 QualType getLocationType() const override {
0652 return locTy;
0653 }
0654
0655 LLVM_ATTRIBUTE_RETURNS_NONNULL
0656 const BlockDecl *getDecl() const {
0657 return BD;
0658 }
0659
0660 LLVM_ATTRIBUTE_RETURNS_NONNULL
0661 AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
0662
0663 void dumpToStream(raw_ostream &os) const override;
0664
0665 void Profile(llvm::FoldingSetNodeID& ID) const override;
0666
0667 static bool classof(const MemRegion* R) {
0668 return R->getKind() == BlockCodeRegionKind;
0669 }
0670 };
0671
0672
0673
0674
0675
0676
0677
0678 class BlockDataRegion : public TypedRegion {
0679 friend class MemRegionManager;
0680
0681 const BlockCodeRegion *BC;
0682 const LocationContext *LC;
0683 unsigned BlockCount;
0684 void *ReferencedVars = nullptr;
0685 void *OriginalVars = nullptr;
0686
0687 BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
0688 unsigned count, const MemSpaceRegion *sreg)
0689 : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
0690 BlockCount(count) {
0691 assert(bc);
0692 assert(bc->getDecl());
0693 assert(lc);
0694 assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
0695 isa<StackLocalsSpaceRegion>(sreg) ||
0696 isa<UnknownSpaceRegion>(sreg));
0697 }
0698
0699 static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
0700 const LocationContext *, unsigned,
0701 const MemRegion *);
0702
0703 public:
0704 LLVM_ATTRIBUTE_RETURNS_NONNULL
0705 const BlockCodeRegion *getCodeRegion() const { return BC; }
0706
0707 LLVM_ATTRIBUTE_RETURNS_NONNULL
0708 const BlockDecl *getDecl() const { return BC->getDecl(); }
0709
0710 QualType getLocationType() const override { return BC->getLocationType(); }
0711
0712 class referenced_vars_iterator {
0713 const MemRegion * const *R;
0714 const MemRegion * const *OriginalR;
0715
0716 public:
0717 explicit referenced_vars_iterator(const MemRegion * const *r,
0718 const MemRegion * const *originalR)
0719 : R(r), OriginalR(originalR) {}
0720
0721 LLVM_ATTRIBUTE_RETURNS_NONNULL
0722 const VarRegion *getCapturedRegion() const {
0723 return cast<VarRegion>(*R);
0724 }
0725
0726 LLVM_ATTRIBUTE_RETURNS_NONNULL
0727 const VarRegion *getOriginalRegion() const {
0728 return cast<VarRegion>(*OriginalR);
0729 }
0730
0731 bool operator==(const referenced_vars_iterator &I) const {
0732 assert((R == nullptr) == (I.R == nullptr));
0733 return I.R == R;
0734 }
0735
0736 bool operator!=(const referenced_vars_iterator &I) const {
0737 assert((R == nullptr) == (I.R == nullptr));
0738 return I.R != R;
0739 }
0740
0741 referenced_vars_iterator &operator++() {
0742 ++R;
0743 ++OriginalR;
0744 return *this;
0745 }
0746
0747
0748
0749
0750 const referenced_vars_iterator &operator*() const { return *this; }
0751 };
0752
0753
0754
0755 const VarRegion *getOriginalRegion(const VarRegion *VR) const;
0756
0757 referenced_vars_iterator referenced_vars_begin() const;
0758 referenced_vars_iterator referenced_vars_end() const;
0759 llvm::iterator_range<referenced_vars_iterator> referenced_vars() const;
0760
0761 void dumpToStream(raw_ostream &os) const override;
0762
0763 void Profile(llvm::FoldingSetNodeID& ID) const override;
0764
0765 static bool classof(const MemRegion* R) {
0766 return R->getKind() == BlockDataRegionKind;
0767 }
0768
0769 private:
0770 void LazyInitializeReferencedVars();
0771 std::pair<const VarRegion *, const VarRegion *>
0772 getCaptureRegions(const VarDecl *VD);
0773 };
0774
0775
0776
0777
0778
0779
0780 class SymbolicRegion : public SubRegion {
0781 friend class MemRegionManager;
0782
0783 const SymbolRef sym;
0784
0785 SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
0786 : SubRegion(sreg, SymbolicRegionKind), sym(s) {
0787
0788
0789 assert(isa_and_nonnull<SymbolData>(s));
0790 assert(s->getType()->isAnyPointerType() ||
0791 s->getType()->isReferenceType() ||
0792 s->getType()->isBlockPointerType());
0793 assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) ||
0794 isa<GlobalSystemSpaceRegion>(sreg));
0795 }
0796
0797 public:
0798
0799 SymbolRef getSymbol() const { return sym; }
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809 QualType getPointeeStaticType() const {
0810 return sym->getType()->getPointeeType();
0811 }
0812
0813 bool isBoundable() const override { return true; }
0814
0815 void Profile(llvm::FoldingSetNodeID& ID) const override;
0816
0817 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
0818 SymbolRef sym,
0819 const MemRegion* superRegion);
0820
0821 void dumpToStream(raw_ostream &os) const override;
0822
0823 static bool classof(const MemRegion* R) {
0824 return R->getKind() == SymbolicRegionKind;
0825 }
0826 };
0827
0828
0829 class StringRegion : public TypedValueRegion {
0830 friend class MemRegionManager;
0831
0832 const StringLiteral *Str;
0833
0834 StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
0835 : TypedValueRegion(sreg, StringRegionKind), Str(str) {
0836 assert(str);
0837 }
0838
0839 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
0840 const StringLiteral *Str,
0841 const MemRegion *superRegion);
0842
0843 public:
0844 LLVM_ATTRIBUTE_RETURNS_NONNULL
0845 const StringLiteral *getStringLiteral() const { return Str; }
0846
0847 QualType getValueType() const override { return Str->getType(); }
0848
0849 bool isBoundable() const override { return false; }
0850
0851 void Profile(llvm::FoldingSetNodeID& ID) const override {
0852 ProfileRegion(ID, Str, superRegion);
0853 }
0854
0855 void dumpToStream(raw_ostream &os) const override;
0856
0857 static bool classof(const MemRegion* R) {
0858 return R->getKind() == StringRegionKind;
0859 }
0860 };
0861
0862
0863 class ObjCStringRegion : public TypedValueRegion {
0864 friend class MemRegionManager;
0865
0866 const ObjCStringLiteral *Str;
0867
0868 ObjCStringRegion(const ObjCStringLiteral *str,
0869 const GlobalInternalSpaceRegion *sreg)
0870 : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
0871 assert(str);
0872 }
0873
0874 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
0875 const ObjCStringLiteral *Str,
0876 const MemRegion *superRegion);
0877
0878 public:
0879 LLVM_ATTRIBUTE_RETURNS_NONNULL
0880 const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
0881
0882 QualType getValueType() const override { return Str->getType(); }
0883
0884 bool isBoundable() const override { return false; }
0885
0886 void Profile(llvm::FoldingSetNodeID& ID) const override {
0887 ProfileRegion(ID, Str, superRegion);
0888 }
0889
0890 void dumpToStream(raw_ostream &os) const override;
0891
0892 static bool classof(const MemRegion* R) {
0893 return R->getKind() == ObjCStringRegionKind;
0894 }
0895 };
0896
0897
0898
0899
0900 class CompoundLiteralRegion : public TypedValueRegion {
0901 friend class MemRegionManager;
0902
0903 const CompoundLiteralExpr *CL;
0904
0905 CompoundLiteralRegion(const CompoundLiteralExpr *cl,
0906 const MemSpaceRegion *sReg)
0907 : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
0908 assert(cl);
0909 assert(isa<GlobalInternalSpaceRegion>(sReg) ||
0910 isa<StackLocalsSpaceRegion>(sReg));
0911 }
0912
0913 static void ProfileRegion(llvm::FoldingSetNodeID& ID,
0914 const CompoundLiteralExpr *CL,
0915 const MemRegion* superRegion);
0916
0917 public:
0918 QualType getValueType() const override { return CL->getType(); }
0919
0920 bool isBoundable() const override { return !CL->isFileScope(); }
0921
0922 void Profile(llvm::FoldingSetNodeID& ID) const override;
0923
0924 void dumpToStream(raw_ostream &os) const override;
0925
0926 LLVM_ATTRIBUTE_RETURNS_NONNULL
0927 const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
0928
0929 static bool classof(const MemRegion* R) {
0930 return R->getKind() == CompoundLiteralRegionKind;
0931 }
0932 };
0933
0934 class DeclRegion : public TypedValueRegion {
0935 protected:
0936 DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) {
0937 assert(classof(this));
0938 }
0939
0940 public:
0941
0942 virtual const ValueDecl *getDecl() const = 0;
0943
0944 static bool classof(const MemRegion* R) {
0945 unsigned k = R->getKind();
0946 return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS;
0947 }
0948 };
0949
0950 class VarRegion : public DeclRegion {
0951 friend class MemRegionManager;
0952
0953 protected:
0954
0955 VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) {
0956
0957
0958
0959
0960 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
0961 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
0962 }
0963
0964 public:
0965
0966 const VarDecl *getDecl() const override = 0;
0967
0968
0969 const StackFrameContext *getStackFrame() const;
0970
0971 QualType getValueType() const override {
0972
0973 return getDecl()->getType();
0974 }
0975
0976 static bool classof(const MemRegion *R) {
0977 unsigned k = R->getKind();
0978 return k >= BEGIN_VAR_REGIONS && k <= END_VAR_REGIONS;
0979 }
0980 };
0981
0982 class NonParamVarRegion : public VarRegion {
0983 friend class MemRegionManager;
0984
0985 const VarDecl *VD;
0986
0987
0988 NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg)
0989 : VarRegion(sReg, NonParamVarRegionKind), VD(vd) {
0990
0991
0992
0993
0994 assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
0995 isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
0996 assert(vd);
0997 }
0998
0999 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD,
1000 const MemRegion *superRegion);
1001
1002 public:
1003 void Profile(llvm::FoldingSetNodeID &ID) const override;
1004
1005 LLVM_ATTRIBUTE_RETURNS_NONNULL
1006 const VarDecl *getDecl() const override { return VD; }
1007
1008 QualType getValueType() const override {
1009
1010 return getDecl()->getType();
1011 }
1012
1013 void dumpToStream(raw_ostream &os) const override;
1014
1015 bool canPrintPrettyAsExpr() const override;
1016
1017 void printPrettyAsExpr(raw_ostream &os) const override;
1018
1019 static bool classof(const MemRegion* R) {
1020 return R->getKind() == NonParamVarRegionKind;
1021 }
1022 };
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034 class ParamVarRegion : public VarRegion {
1035 friend class MemRegionManager;
1036
1037 const Expr *OriginExpr;
1038 unsigned Index;
1039
1040 ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg)
1041 : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) {
1042 assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame());
1043 assert(OriginExpr);
1044 }
1045
1046 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
1047 unsigned Idx, const MemRegion *SReg);
1048
1049 public:
1050 LLVM_ATTRIBUTE_RETURNS_NONNULL
1051 const Expr *getOriginExpr() const { return OriginExpr; }
1052 unsigned getIndex() const { return Index; }
1053
1054 void Profile(llvm::FoldingSetNodeID& ID) const override;
1055
1056 void dumpToStream(raw_ostream &os) const override;
1057
1058 QualType getValueType() const override;
1059
1060
1061 const ParmVarDecl *getDecl() const override;
1062
1063 bool canPrintPrettyAsExpr() const override;
1064 void printPrettyAsExpr(raw_ostream &os) const override;
1065
1066 static bool classof(const MemRegion *R) {
1067 return R->getKind() == ParamVarRegionKind;
1068 }
1069 };
1070
1071
1072
1073
1074 class CXXThisRegion : public TypedValueRegion {
1075 friend class MemRegionManager;
1076
1077 CXXThisRegion(const PointerType *thisPointerTy,
1078 const StackArgumentsSpaceRegion *sReg)
1079 : TypedValueRegion(sReg, CXXThisRegionKind),
1080 ThisPointerTy(thisPointerTy) {
1081 assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
1082 "Invalid region type!");
1083 }
1084
1085 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1086 const PointerType *PT,
1087 const MemRegion *sReg);
1088
1089 public:
1090 void Profile(llvm::FoldingSetNodeID &ID) const override;
1091
1092 QualType getValueType() const override {
1093 return QualType(ThisPointerTy, 0);
1094 }
1095
1096 void dumpToStream(raw_ostream &os) const override;
1097
1098 static bool classof(const MemRegion* R) {
1099 return R->getKind() == CXXThisRegionKind;
1100 }
1101
1102 private:
1103 const PointerType *ThisPointerTy;
1104 };
1105
1106 class FieldRegion : public DeclRegion {
1107 friend class MemRegionManager;
1108
1109 const FieldDecl *FD;
1110
1111 FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
1112 : DeclRegion(sReg, FieldRegionKind), FD(fd) {
1113 assert(FD);
1114 }
1115
1116 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD,
1117 const MemRegion* superRegion) {
1118 ID.AddInteger(static_cast<unsigned>(FieldRegionKind));
1119 ID.AddPointer(FD);
1120 ID.AddPointer(superRegion);
1121 }
1122
1123 public:
1124 LLVM_ATTRIBUTE_RETURNS_NONNULL
1125 const FieldDecl *getDecl() const override { return FD; }
1126
1127 void Profile(llvm::FoldingSetNodeID &ID) const override;
1128
1129 QualType getValueType() const override {
1130
1131 return getDecl()->getType();
1132 }
1133
1134 void dumpToStream(raw_ostream &os) const override;
1135
1136 bool canPrintPretty() const override;
1137 void printPretty(raw_ostream &os) const override;
1138 bool canPrintPrettyAsExpr() const override;
1139 void printPrettyAsExpr(raw_ostream &os) const override;
1140
1141 static bool classof(const MemRegion* R) {
1142 return R->getKind() == FieldRegionKind;
1143 }
1144 };
1145
1146 class ObjCIvarRegion : public DeclRegion {
1147 friend class MemRegionManager;
1148
1149 const ObjCIvarDecl *IVD;
1150
1151 ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
1152
1153 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
1154 const MemRegion* superRegion);
1155
1156 public:
1157 LLVM_ATTRIBUTE_RETURNS_NONNULL
1158 const ObjCIvarDecl *getDecl() const override;
1159
1160 void Profile(llvm::FoldingSetNodeID& ID) const override;
1161
1162 QualType getValueType() const override;
1163
1164 bool canPrintPrettyAsExpr() const override;
1165 void printPrettyAsExpr(raw_ostream &os) const override;
1166
1167 void dumpToStream(raw_ostream &os) const override;
1168
1169 static bool classof(const MemRegion* R) {
1170 return R->getKind() == ObjCIvarRegionKind;
1171 }
1172 };
1173
1174
1175
1176
1177
1178 class RegionRawOffset {
1179 friend class ElementRegion;
1180
1181 const MemRegion *Region;
1182 CharUnits Offset;
1183
1184 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
1185 : Region(reg), Offset(offset) {}
1186
1187 public:
1188
1189 CharUnits getOffset() const { return Offset; }
1190
1191
1192 const MemRegion *getRegion() const { return Region; }
1193
1194 void dumpToStream(raw_ostream &os) const;
1195 void dump() const;
1196 };
1197
1198
1199 class ElementRegion : public TypedValueRegion {
1200 friend class MemRegionManager;
1201
1202 QualType ElementType;
1203 NonLoc Index;
1204
1205 ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
1206 : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
1207 Index(Idx) {
1208 assert((!isa<nonloc::ConcreteInt>(Idx) ||
1209 Idx.castAs<nonloc::ConcreteInt>().getValue()->isSigned()) &&
1210 "The index must be signed");
1211 assert(!elementType.isNull() && !elementType->isVoidType() &&
1212 "Invalid region type!");
1213 }
1214
1215 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
1216 SVal Idx, const MemRegion* superRegion);
1217
1218 public:
1219 NonLoc getIndex() const { return Index; }
1220
1221 QualType getValueType() const override { return ElementType; }
1222
1223 QualType getElementType() const { return ElementType; }
1224
1225
1226 RegionRawOffset getAsArrayOffset() const;
1227
1228 void dumpToStream(raw_ostream &os) const override;
1229
1230 void Profile(llvm::FoldingSetNodeID& ID) const override;
1231
1232 static bool classof(const MemRegion* R) {
1233 return R->getKind() == ElementRegionKind;
1234 }
1235 };
1236
1237
1238 class CXXTempObjectRegion : public TypedValueRegion {
1239 friend class MemRegionManager;
1240
1241 Expr const *Ex;
1242
1243 CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
1244 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
1245 assert(E);
1246 assert(isa<StackLocalsSpaceRegion>(sReg));
1247 }
1248
1249 static void ProfileRegion(llvm::FoldingSetNodeID &ID,
1250 Expr const *E, const MemRegion *sReg);
1251
1252 public:
1253 LLVM_ATTRIBUTE_RETURNS_NONNULL
1254 const Expr *getExpr() const { return Ex; }
1255
1256 LLVM_ATTRIBUTE_RETURNS_NONNULL
1257 const StackFrameContext *getStackFrame() const;
1258
1259 QualType getValueType() const override { return Ex->getType(); }
1260
1261 void dumpToStream(raw_ostream &os) const override;
1262
1263 void Profile(llvm::FoldingSetNodeID &ID) const override;
1264
1265 static bool classof(const MemRegion* R) {
1266 return R->getKind() == CXXTempObjectRegionKind;
1267 }
1268 };
1269
1270
1271
1272 class CXXLifetimeExtendedObjectRegion : public TypedValueRegion {
1273 friend class MemRegionManager;
1274
1275 Expr const *Ex;
1276 ValueDecl const *ExD;
1277
1278 CXXLifetimeExtendedObjectRegion(Expr const *E, ValueDecl const *D,
1279 MemSpaceRegion const *sReg)
1280 : TypedValueRegion(sReg, CXXLifetimeExtendedObjectRegionKind), Ex(E),
1281 ExD(D) {
1282 assert(E);
1283 assert(D);
1284 assert((isa<StackLocalsSpaceRegion, GlobalInternalSpaceRegion>(sReg)));
1285 }
1286
1287 static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E,
1288 ValueDecl const *D, const MemRegion *sReg);
1289
1290 public:
1291 LLVM_ATTRIBUTE_RETURNS_NONNULL
1292 const Expr *getExpr() const { return Ex; }
1293 LLVM_ATTRIBUTE_RETURNS_NONNULL
1294 const ValueDecl *getExtendingDecl() const { return ExD; }
1295
1296 const StackFrameContext *getStackFrame() const;
1297
1298 QualType getValueType() const override { return Ex->getType(); }
1299
1300 void dumpToStream(raw_ostream &os) const override;
1301
1302 void Profile(llvm::FoldingSetNodeID &ID) const override;
1303
1304 static bool classof(const MemRegion *R) {
1305 return R->getKind() == CXXLifetimeExtendedObjectRegionKind;
1306 }
1307 };
1308
1309
1310
1311 class CXXBaseObjectRegion : public TypedValueRegion {
1312 friend class MemRegionManager;
1313
1314 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
1315
1316 CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
1317 const SubRegion *SReg)
1318 : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
1319 assert(RD);
1320 }
1321
1322 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1323 bool IsVirtual, const MemRegion *SReg);
1324
1325 public:
1326 LLVM_ATTRIBUTE_RETURNS_NONNULL
1327 const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
1328 bool isVirtual() const { return Data.getInt(); }
1329
1330 QualType getValueType() const override;
1331
1332 void dumpToStream(raw_ostream &os) const override;
1333
1334 void Profile(llvm::FoldingSetNodeID &ID) const override;
1335
1336 bool canPrintPrettyAsExpr() const override;
1337
1338 void printPrettyAsExpr(raw_ostream &os) const override;
1339
1340 static bool classof(const MemRegion *region) {
1341 return region->getKind() == CXXBaseObjectRegionKind;
1342 }
1343 };
1344
1345
1346
1347
1348
1349
1350 class CXXDerivedObjectRegion : public TypedValueRegion {
1351 friend class MemRegionManager;
1352
1353 const CXXRecordDecl *DerivedD;
1354
1355 CXXDerivedObjectRegion(const CXXRecordDecl *DerivedD, const SubRegion *SReg)
1356 : TypedValueRegion(SReg, CXXDerivedObjectRegionKind), DerivedD(DerivedD) {
1357 assert(DerivedD);
1358
1359
1360
1361 assert(SReg->getSymbolicBase() &&
1362 "Should have unwrapped a base region instead!");
1363 }
1364
1365 static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
1366 const MemRegion *SReg);
1367
1368 public:
1369 LLVM_ATTRIBUTE_RETURNS_NONNULL
1370 const CXXRecordDecl *getDecl() const { return DerivedD; }
1371
1372 QualType getValueType() const override;
1373
1374 void dumpToStream(raw_ostream &os) const override;
1375
1376 void Profile(llvm::FoldingSetNodeID &ID) const override;
1377
1378 bool canPrintPrettyAsExpr() const override;
1379
1380 void printPrettyAsExpr(raw_ostream &os) const override;
1381
1382 static bool classof(const MemRegion *region) {
1383 return region->getKind() == CXXDerivedObjectRegionKind;
1384 }
1385 };
1386
1387 template<typename RegionTy>
1388 const RegionTy* MemRegion::getAs() const {
1389 if (const auto *RT = dyn_cast<RegionTy>(this))
1390 return RT;
1391
1392 return nullptr;
1393 }
1394
1395 template <typename RegionTy>
1396 LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const {
1397 return cast<RegionTy>(this);
1398 }
1399
1400
1401
1402
1403
1404 class MemRegionManager {
1405 ASTContext &Ctx;
1406 llvm::BumpPtrAllocator& A;
1407
1408 llvm::FoldingSet<MemRegion> Regions;
1409
1410 GlobalInternalSpaceRegion *InternalGlobals = nullptr;
1411 GlobalSystemSpaceRegion *SystemGlobals = nullptr;
1412 GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
1413
1414 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
1415 StackLocalsSpaceRegions;
1416 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
1417 StackArgumentsSpaceRegions;
1418 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
1419 StaticsGlobalSpaceRegions;
1420
1421 HeapSpaceRegion *heap = nullptr;
1422 UnknownSpaceRegion *unknown = nullptr;
1423 CodeSpaceRegion *code = nullptr;
1424
1425 public:
1426 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
1427 ~MemRegionManager();
1428
1429 ASTContext &getContext() { return Ctx; }
1430 const ASTContext &getContext() const { return Ctx; }
1431
1432 llvm::BumpPtrAllocator &getAllocator() { return A; }
1433
1434
1435
1436 DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
1437 SValBuilder &SVB) const;
1438
1439
1440
1441 const StackLocalsSpaceRegion *
1442 getStackLocalsRegion(const StackFrameContext *STC);
1443
1444
1445
1446 const StackArgumentsSpaceRegion *
1447 getStackArgumentsRegion(const StackFrameContext *STC);
1448
1449
1450
1451 const GlobalsSpaceRegion *getGlobalsRegion(
1452 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
1453 const CodeTextRegion *R = nullptr);
1454
1455
1456
1457 const HeapSpaceRegion *getHeapRegion();
1458
1459
1460
1461 const UnknownSpaceRegion *getUnknownRegion();
1462
1463 const CodeSpaceRegion *getCodeRegion();
1464
1465
1466 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
1467 const LocationContext *LC);
1468
1469
1470
1471 const CompoundLiteralRegion*
1472 getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
1473 const LocationContext *LC);
1474
1475
1476
1477 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
1478 const LocationContext *LC);
1479
1480
1481
1482 const SymbolicRegion *
1483 getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr);
1484
1485
1486 const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
1487
1488 const StringRegion *getStringRegion(const StringLiteral *Str);
1489
1490 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
1491
1492
1493
1494 const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC);
1495
1496
1497
1498 const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD,
1499 const MemRegion *superR);
1500
1501
1502
1503 const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr,
1504 unsigned Index,
1505 const LocationContext *LC);
1506
1507
1508
1509 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
1510 const SubRegion *superRegion,
1511 const ASTContext &Ctx);
1512
1513 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
1514 const SubRegion *superRegion) {
1515 return getElementRegion(ER->getElementType(), ER->getIndex(),
1516 superRegion, ER->getContext());
1517 }
1518
1519
1520
1521
1522
1523 const FieldRegion *getFieldRegion(const FieldDecl *fd,
1524 const SubRegion* superRegion);
1525
1526 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
1527 const SubRegion *superRegion) {
1528 return getFieldRegion(FR->getDecl(), superRegion);
1529 }
1530
1531
1532
1533
1534
1535 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
1536 const SubRegion* superRegion);
1537
1538 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
1539 LocationContext const *LC);
1540
1541
1542
1543 const CXXLifetimeExtendedObjectRegion *
1544 getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD,
1545 LocationContext const *LC);
1546
1547
1548
1549
1550
1551 const CXXLifetimeExtendedObjectRegion *
1552 getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD);
1553
1554
1555
1556
1557
1558 const CXXBaseObjectRegion *
1559 getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
1560 bool IsVirtual);
1561
1562
1563
1564 const CXXBaseObjectRegion *
1565 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
1566 const SubRegion *superRegion) {
1567 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
1568 baseReg->isVirtual());
1569 }
1570
1571
1572
1573
1574
1575 const CXXDerivedObjectRegion *
1576 getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass,
1577 const SubRegion *Super);
1578
1579 const FunctionCodeRegion *getFunctionCodeRegion(const NamedDecl *FD);
1580 const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD,
1581 CanQualType locTy,
1582 AnalysisDeclContext *AC);
1583
1584
1585
1586
1587
1588 const BlockDataRegion *getBlockDataRegion(const BlockCodeRegion *bc,
1589 const LocationContext *lc,
1590 unsigned blockCount);
1591
1592 private:
1593 template <typename RegionTy, typename SuperTy,
1594 typename Arg1Ty>
1595 RegionTy* getSubRegion(const Arg1Ty arg1,
1596 const SuperTy* superRegion);
1597
1598 template <typename RegionTy, typename SuperTy,
1599 typename Arg1Ty, typename Arg2Ty>
1600 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1601 const SuperTy* superRegion);
1602
1603 template <typename RegionTy, typename SuperTy,
1604 typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
1605 RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
1606 const Arg3Ty arg3,
1607 const SuperTy* superRegion);
1608
1609 template <typename REG>
1610 const REG* LazyAllocate(REG*& region);
1611
1612 template <typename REG, typename ARG>
1613 const REG* LazyAllocate(REG*& region, ARG a);
1614 };
1615
1616
1617
1618
1619
1620 inline ASTContext &MemRegion::getContext() const {
1621 return getMemRegionManager().getContext();
1622 }
1623
1624
1625
1626
1627
1628
1629 class RegionAndSymbolInvalidationTraits {
1630 using StorageTypeForKinds = unsigned char;
1631
1632 llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
1633 llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
1634
1635 using const_region_iterator =
1636 llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
1637 using const_symbol_iterator =
1638 llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
1639
1640 public:
1641
1642 enum InvalidationKinds {
1643
1644 TK_PreserveContents = 0x1,
1645
1646
1647 TK_SuppressEscape = 0x2,
1648
1649
1650 TK_DoNotInvalidateSuperRegion = 0x4,
1651
1652
1653
1654 TK_EntireMemSpace = 0x8
1655
1656
1657
1658 };
1659
1660 void setTrait(SymbolRef Sym, InvalidationKinds IK);
1661 void setTrait(const MemRegion *MR, InvalidationKinds IK);
1662 bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
1663 bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
1664 };
1665
1666
1667
1668
1669 inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
1670 R->dumpToStream(os);
1671 return os;
1672 }
1673
1674 }
1675
1676 }
1677
1678 #endif