File indexing completed on 2026-05-10 08:37:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H
0014 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H
0015
0016 #include "clang/Basic/LLVM.h"
0017 #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
0018 #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
0019 #include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
0020 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0021 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
0022 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
0023 #include "llvm/ADT/FoldingSet.h"
0024 #include "llvm/ADT/ImmutableMap.h"
0025 #include "llvm/Support/Allocator.h"
0026 #include <optional>
0027 #include <utility>
0028
0029 namespace llvm {
0030 class APSInt;
0031 }
0032
0033 namespace clang {
0034 class ASTContext;
0035
0036 namespace ento {
0037
0038 class AnalysisManager;
0039 class CallEvent;
0040 class CallEventManager;
0041
0042 typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)(
0043 ProgramStateManager &, ExprEngine *);
0044 typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)(
0045 ProgramStateManager &);
0046
0047
0048
0049
0050
0051 template <typename T> struct ProgramStateTrait {
0052 typedef typename T::data_type data_type;
0053 static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
0054 static inline data_type MakeData(void *const* P) {
0055 return P ? (data_type) *P : (data_type) 0;
0056 }
0057 };
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 class ProgramState : public llvm::FoldingSetNode {
0072 public:
0073 typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
0074
0075 private:
0076 void operator=(const ProgramState& R) = delete;
0077
0078 friend class ProgramStateManager;
0079 friend class ExplodedGraph;
0080 friend class ExplodedNode;
0081 friend class NodeBuilder;
0082
0083 ProgramStateManager *stateMgr;
0084 Environment Env;
0085 Store store;
0086 GenericDataMap GDM;
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 bool PosteriorlyOverconstrained = false;
0115
0116
0117
0118 friend class ConstraintManager;
0119 bool isPosteriorlyOverconstrained() const {
0120 return PosteriorlyOverconstrained;
0121 }
0122 ProgramStateRef cloneAsPosteriorlyOverconstrained() const;
0123
0124 unsigned refCount;
0125
0126
0127
0128 ProgramStateRef makeWithStore(const StoreRef &store) const;
0129
0130 void setStore(const StoreRef &storeRef);
0131
0132 public:
0133
0134 ProgramState(ProgramStateManager *mgr, const Environment& env,
0135 StoreRef st, GenericDataMap gdm);
0136
0137
0138
0139 ProgramState(const ProgramState &RHS);
0140
0141 ~ProgramState();
0142
0143 int64_t getID() const;
0144
0145
0146 ProgramStateManager &getStateManager() const {
0147 return *stateMgr;
0148 }
0149
0150 AnalysisManager &getAnalysisManager() const;
0151
0152
0153 ConstraintManager &getConstraintManager() const;
0154
0155
0156
0157 const Environment& getEnvironment() const { return Env; }
0158
0159
0160
0161 Store getStore() const { return store; }
0162
0163
0164
0165 GenericDataMap getGDM() const { return GDM; }
0166
0167 void setGDM(GenericDataMap gdm) { GDM = gdm; }
0168
0169
0170
0171
0172 static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
0173 V->Env.Profile(ID);
0174 ID.AddPointer(V->store);
0175 V->GDM.Profile(ID);
0176 ID.AddBoolean(V->PosteriorlyOverconstrained);
0177 }
0178
0179
0180
0181 void Profile(llvm::FoldingSetNodeID& ID) const {
0182 Profile(ID, this);
0183 }
0184
0185 BasicValueFactory &getBasicVals() const;
0186 SymbolManager &getSymbolManager() const;
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 [[nodiscard]] ProgramStateRef assume(DefinedOrUnknownSVal cond,
0220 bool assumption) const;
0221
0222
0223
0224
0225
0226
0227 [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
0228 assume(DefinedOrUnknownSVal cond) const;
0229
0230 [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
0231 assumeInBoundDual(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
0232 QualType IndexType = QualType()) const;
0233
0234 [[nodiscard]] ProgramStateRef
0235 assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
0236 bool assumption, QualType IndexType = QualType()) const;
0237
0238
0239
0240
0241
0242
0243
0244 [[nodiscard]] ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
0245 const llvm::APSInt &From,
0246 const llvm::APSInt &To,
0247 bool assumption) const;
0248
0249
0250
0251
0252
0253
0254 [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
0255 assumeInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
0256 const llvm::APSInt &To) const;
0257
0258
0259
0260 ConditionTruthVal isNonNull(SVal V) const;
0261
0262
0263
0264 ConditionTruthVal isNull(SVal V) const;
0265
0266
0267 ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const;
0268
0269
0270 LLVM_ATTRIBUTE_RETURNS_NONNULL
0271 const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
0272
0273
0274
0275
0276
0277
0278
0279 [[nodiscard]] ProgramStateRef BindExpr(const Stmt *S,
0280 const LocationContext *LCtx, SVal V,
0281 bool Invalidate = true) const;
0282
0283 [[nodiscard]] ProgramStateRef bindLoc(Loc location, SVal V,
0284 const LocationContext *LCtx,
0285 bool notifyChanges = true) const;
0286
0287 [[nodiscard]] ProgramStateRef bindLoc(SVal location, SVal V,
0288 const LocationContext *LCtx) const;
0289
0290
0291
0292
0293
0294
0295
0296 [[nodiscard]] ProgramStateRef
0297 bindDefaultInitial(SVal loc, SVal V, const LocationContext *LCtx) const;
0298
0299
0300
0301 [[nodiscard]] ProgramStateRef
0302 bindDefaultZero(SVal loc, const LocationContext *LCtx) const;
0303
0304 [[nodiscard]] ProgramStateRef killBinding(Loc LV) const;
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 [[nodiscard]] ProgramStateRef
0328 invalidateRegions(ArrayRef<const MemRegion *> Regions, const Stmt *S,
0329 unsigned BlockCount, const LocationContext *LCtx,
0330 bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
0331 const CallEvent *Call = nullptr,
0332 RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
0333
0334 [[nodiscard]] ProgramStateRef
0335 invalidateRegions(ArrayRef<SVal> Values, const Stmt *S, unsigned BlockCount,
0336 const LocationContext *LCtx, bool CausesPointerEscape,
0337 InvalidatedSymbols *IS = nullptr,
0338 const CallEvent *Call = nullptr,
0339 RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
0340
0341
0342
0343 [[nodiscard]] ProgramStateRef
0344 enterStackFrame(const CallEvent &Call,
0345 const StackFrameContext *CalleeCtx) const;
0346
0347
0348 SVal getSelfSVal(const LocationContext *LC) const;
0349
0350
0351 Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const;
0352
0353
0354 Loc getLValue(const CXXRecordDecl *BaseClass, const SubRegion *Super,
0355 bool IsVirtual) const;
0356
0357
0358 Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
0359
0360 Loc getLValue(const CompoundLiteralExpr *literal,
0361 const LocationContext *LC) const;
0362
0363
0364 SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
0365
0366
0367 SVal getLValue(const FieldDecl *decl, SVal Base) const;
0368
0369
0370 SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const;
0371
0372
0373 SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
0374
0375
0376 SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
0377
0378 SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
0379
0380
0381
0382 SVal getSVal(Loc LV, QualType T = QualType()) const;
0383
0384
0385 SVal getRawSVal(Loc LV, QualType T= QualType()) const;
0386
0387
0388
0389 SVal getSVal(const MemRegion* R, QualType T = QualType()) const;
0390
0391
0392
0393
0394
0395 SVal getSValAsScalarOrLoc(const MemRegion *R) const;
0396
0397 using region_iterator = const MemRegion **;
0398
0399
0400
0401
0402
0403
0404
0405
0406 bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
0407
0408
0409
0410 bool scanReachableSymbols(llvm::iterator_range<region_iterator> Reachable,
0411 SymbolVisitor &visitor) const;
0412
0413 template <typename CB> CB scanReachableSymbols(SVal val) const;
0414 template <typename CB> CB
0415 scanReachableSymbols(llvm::iterator_range<region_iterator> Reachable) const;
0416
0417
0418
0419
0420
0421 void *const* FindGDM(void *K) const;
0422
0423 template <typename T>
0424 [[nodiscard]] ProgramStateRef
0425 add(typename ProgramStateTrait<T>::key_type K) const;
0426
0427 template <typename T>
0428 typename ProgramStateTrait<T>::data_type
0429 get() const {
0430 return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
0431 }
0432
0433 template<typename T>
0434 typename ProgramStateTrait<T>::lookup_type
0435 get(typename ProgramStateTrait<T>::key_type key) const {
0436 void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
0437 return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
0438 }
0439
0440 template <typename T>
0441 typename ProgramStateTrait<T>::context_type get_context() const;
0442
0443 template <typename T>
0444 [[nodiscard]] ProgramStateRef
0445 remove(typename ProgramStateTrait<T>::key_type K) const;
0446
0447 template <typename T>
0448 [[nodiscard]] ProgramStateRef
0449 remove(typename ProgramStateTrait<T>::key_type K,
0450 typename ProgramStateTrait<T>::context_type C) const;
0451
0452 template <typename T> [[nodiscard]] ProgramStateRef remove() const;
0453
0454 template <typename T>
0455 [[nodiscard]] ProgramStateRef
0456 set(typename ProgramStateTrait<T>::data_type D) const;
0457
0458 template <typename T>
0459 [[nodiscard]] ProgramStateRef
0460 set(typename ProgramStateTrait<T>::key_type K,
0461 typename ProgramStateTrait<T>::value_type E) const;
0462
0463 template <typename T>
0464 [[nodiscard]] ProgramStateRef
0465 set(typename ProgramStateTrait<T>::key_type K,
0466 typename ProgramStateTrait<T>::value_type E,
0467 typename ProgramStateTrait<T>::context_type C) const;
0468
0469 template<typename T>
0470 bool contains(typename ProgramStateTrait<T>::key_type key) const {
0471 void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
0472 return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
0473 }
0474
0475
0476 void printJson(raw_ostream &Out, const LocationContext *LCtx = nullptr,
0477 const char *NL = "\n", unsigned int Space = 0,
0478 bool IsDot = false) const;
0479
0480 void printDOT(raw_ostream &Out, const LocationContext *LCtx = nullptr,
0481 unsigned int Space = 0) const;
0482
0483 void dump() const;
0484
0485 private:
0486 friend void ProgramStateRetain(const ProgramState *state);
0487 friend void ProgramStateRelease(const ProgramState *state);
0488
0489 SVal desugarReference(SVal Val) const;
0490 SVal wrapSymbolicRegion(SVal Base) const;
0491 };
0492
0493
0494
0495
0496
0497 class ProgramStateManager {
0498 friend class ProgramState;
0499 friend void ProgramStateRelease(const ProgramState *state);
0500 private:
0501
0502 ExprEngine *Eng;
0503
0504 EnvironmentManager EnvMgr;
0505 std::unique_ptr<StoreManager> StoreMgr;
0506 std::unique_ptr<ConstraintManager> ConstraintMgr;
0507
0508 ProgramState::GenericDataMap::Factory GDMFactory;
0509
0510 typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
0511 GDMContextsTy GDMContexts;
0512
0513
0514
0515 llvm::FoldingSet<ProgramState> StateSet;
0516
0517
0518 std::unique_ptr<SValBuilder> svalBuilder;
0519
0520
0521 std::unique_ptr<CallEventManager> CallEventMgr;
0522
0523
0524 llvm::BumpPtrAllocator &Alloc;
0525
0526
0527 std::vector<ProgramState *> freeStates;
0528
0529 public:
0530 ProgramStateManager(ASTContext &Ctx,
0531 StoreManagerCreator CreateStoreManager,
0532 ConstraintManagerCreator CreateConstraintManager,
0533 llvm::BumpPtrAllocator& alloc,
0534 ExprEngine *expreng);
0535
0536 ~ProgramStateManager();
0537
0538 ProgramStateRef getInitialState(const LocationContext *InitLoc);
0539
0540 ASTContext &getContext() { return svalBuilder->getContext(); }
0541 const ASTContext &getContext() const { return svalBuilder->getContext(); }
0542
0543 BasicValueFactory &getBasicVals() {
0544 return svalBuilder->getBasicValueFactory();
0545 }
0546
0547 SValBuilder &getSValBuilder() {
0548 return *svalBuilder;
0549 }
0550
0551 const SValBuilder &getSValBuilder() const {
0552 return *svalBuilder;
0553 }
0554
0555 SymbolManager &getSymbolManager() {
0556 return svalBuilder->getSymbolManager();
0557 }
0558 const SymbolManager &getSymbolManager() const {
0559 return svalBuilder->getSymbolManager();
0560 }
0561
0562 llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
0563
0564 MemRegionManager& getRegionManager() {
0565 return svalBuilder->getRegionManager();
0566 }
0567 const MemRegionManager &getRegionManager() const {
0568 return svalBuilder->getRegionManager();
0569 }
0570
0571 CallEventManager &getCallEventManager() { return *CallEventMgr; }
0572
0573 StoreManager &getStoreManager() { return *StoreMgr; }
0574 ConstraintManager &getConstraintManager() { return *ConstraintMgr; }
0575 ExprEngine &getOwningEngine() { return *Eng; }
0576
0577 ProgramStateRef
0578 removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St,
0579 const StackFrameContext *LCtx,
0580 SymbolReaper &SymReaper);
0581
0582 public:
0583
0584 SVal ArrayToPointer(Loc Array, QualType ElementTy) {
0585 return StoreMgr->ArrayToPointer(Array, ElementTy);
0586 }
0587
0588
0589 ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
0590 ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
0591
0592
0593
0594 void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
0595 StoreMgr->iterBindings(state->getStore(), F);
0596 }
0597
0598 ProgramStateRef getPersistentState(ProgramState &Impl);
0599 ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
0600 ProgramStateRef GDMState);
0601
0602 bool haveEqualConstraints(ProgramStateRef S1, ProgramStateRef S2) const {
0603 return ConstraintMgr->haveEqualConstraints(S1, S2);
0604 }
0605
0606 bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) const {
0607 return S1->Env == S2->Env;
0608 }
0609
0610 bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) const {
0611 return S1->store == S2->store;
0612 }
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633 template <typename T>
0634 ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
0635 return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
0636 ProgramStateTrait<T>::MakeVoidPtr(D));
0637 }
0638
0639 template<typename T>
0640 ProgramStateRef set(ProgramStateRef st,
0641 typename ProgramStateTrait<T>::key_type K,
0642 typename ProgramStateTrait<T>::value_type V,
0643 typename ProgramStateTrait<T>::context_type C) {
0644
0645 return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
0646 ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
0647 }
0648
0649 template <typename T>
0650 ProgramStateRef add(ProgramStateRef st,
0651 typename ProgramStateTrait<T>::key_type K,
0652 typename ProgramStateTrait<T>::context_type C) {
0653 return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
0654 ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
0655 }
0656
0657 template <typename T>
0658 ProgramStateRef remove(ProgramStateRef st,
0659 typename ProgramStateTrait<T>::key_type K,
0660 typename ProgramStateTrait<T>::context_type C) {
0661
0662 return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
0663 ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
0664 }
0665
0666 template <typename T>
0667 ProgramStateRef remove(ProgramStateRef st) {
0668 return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
0669 }
0670
0671 void *FindGDMContext(void *index,
0672 void *(*CreateContext)(llvm::BumpPtrAllocator&),
0673 void (*DeleteContext)(void*));
0674
0675 template <typename T>
0676 typename ProgramStateTrait<T>::context_type get_context() {
0677 void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
0678 ProgramStateTrait<T>::CreateContext,
0679 ProgramStateTrait<T>::DeleteContext);
0680
0681 return ProgramStateTrait<T>::MakeContext(p);
0682 }
0683 };
0684
0685
0686
0687
0688
0689
0690 inline ConstraintManager &ProgramState::getConstraintManager() const {
0691 return stateMgr->getConstraintManager();
0692 }
0693
0694 inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
0695 const LocationContext *LC) const
0696 {
0697 return getStateManager().getRegionManager().getVarRegion(D, LC);
0698 }
0699
0700 inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
0701 bool Assumption) const {
0702 if (Cond.isUnknown())
0703 return this;
0704
0705 return getStateManager().ConstraintMgr
0706 ->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
0707 }
0708
0709 inline std::pair<ProgramStateRef , ProgramStateRef >
0710 ProgramState::assume(DefinedOrUnknownSVal Cond) const {
0711 if (Cond.isUnknown())
0712 return std::make_pair(this, this);
0713
0714 return getStateManager().ConstraintMgr
0715 ->assumeDual(this, Cond.castAs<DefinedSVal>());
0716 }
0717
0718 inline ProgramStateRef ProgramState::assumeInclusiveRange(
0719 DefinedOrUnknownSVal Val, const llvm::APSInt &From, const llvm::APSInt &To,
0720 bool Assumption) const {
0721 if (Val.isUnknown())
0722 return this;
0723
0724 assert(isa<NonLoc>(Val) && "Only NonLocs are supported!");
0725
0726 return getStateManager().ConstraintMgr->assumeInclusiveRange(
0727 this, Val.castAs<NonLoc>(), From, To, Assumption);
0728 }
0729
0730 inline std::pair<ProgramStateRef, ProgramStateRef>
0731 ProgramState::assumeInclusiveRange(DefinedOrUnknownSVal Val,
0732 const llvm::APSInt &From,
0733 const llvm::APSInt &To) const {
0734 if (Val.isUnknown())
0735 return std::make_pair(this, this);
0736
0737 assert(isa<NonLoc>(Val) && "Only NonLocs are supported!");
0738
0739 return getStateManager().ConstraintMgr->assumeInclusiveRangeDual(
0740 this, Val.castAs<NonLoc>(), From, To);
0741 }
0742
0743 inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const {
0744 if (std::optional<Loc> L = LV.getAs<Loc>())
0745 return bindLoc(*L, V, LCtx);
0746 return this;
0747 }
0748
0749 inline Loc ProgramState::getLValue(const CXXBaseSpecifier &BaseSpec,
0750 const SubRegion *Super) const {
0751 const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl();
0752 return loc::MemRegionVal(
0753 getStateManager().getRegionManager().getCXXBaseObjectRegion(
0754 Base, Super, BaseSpec.isVirtual()));
0755 }
0756
0757 inline Loc ProgramState::getLValue(const CXXRecordDecl *BaseClass,
0758 const SubRegion *Super,
0759 bool IsVirtual) const {
0760 return loc::MemRegionVal(
0761 getStateManager().getRegionManager().getCXXBaseObjectRegion(
0762 BaseClass, Super, IsVirtual));
0763 }
0764
0765 inline Loc ProgramState::getLValue(const VarDecl *VD,
0766 const LocationContext *LC) const {
0767 return getStateManager().StoreMgr->getLValueVar(VD, LC);
0768 }
0769
0770 inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
0771 const LocationContext *LC) const {
0772 return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
0773 }
0774
0775 inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
0776 return getStateManager().StoreMgr->getLValueIvar(D, Base);
0777 }
0778
0779 inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
0780 if (std::optional<NonLoc> N = Idx.getAs<NonLoc>())
0781 return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
0782 return UnknownVal();
0783 }
0784
0785 inline SVal ProgramState::getSVal(const Stmt *Ex,
0786 const LocationContext *LCtx) const{
0787 return Env.getSVal(EnvironmentEntry(Ex, LCtx),
0788 *getStateManager().svalBuilder);
0789 }
0790
0791 inline SVal
0792 ProgramState::getSValAsScalarOrLoc(const Stmt *S,
0793 const LocationContext *LCtx) const {
0794 if (const Expr *Ex = dyn_cast<Expr>(S)) {
0795 QualType T = Ex->getType();
0796 if (Ex->isGLValue() || Loc::isLocType(T) ||
0797 T->isIntegralOrEnumerationType())
0798 return getSVal(S, LCtx);
0799 }
0800
0801 return UnknownVal();
0802 }
0803
0804 inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
0805 return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
0806 }
0807
0808 inline SVal ProgramState::getSVal(const MemRegion* R, QualType T) const {
0809 return getStateManager().StoreMgr->getBinding(getStore(),
0810 loc::MemRegionVal(R),
0811 T);
0812 }
0813
0814 inline BasicValueFactory &ProgramState::getBasicVals() const {
0815 return getStateManager().getBasicVals();
0816 }
0817
0818 inline SymbolManager &ProgramState::getSymbolManager() const {
0819 return getStateManager().getSymbolManager();
0820 }
0821
0822 template<typename T>
0823 ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
0824 return getStateManager().add<T>(this, K, get_context<T>());
0825 }
0826
0827 template <typename T>
0828 typename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
0829 return getStateManager().get_context<T>();
0830 }
0831
0832 template<typename T>
0833 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
0834 return getStateManager().remove<T>(this, K, get_context<T>());
0835 }
0836
0837 template<typename T>
0838 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
0839 typename ProgramStateTrait<T>::context_type C) const {
0840 return getStateManager().remove<T>(this, K, C);
0841 }
0842
0843 template <typename T>
0844 ProgramStateRef ProgramState::remove() const {
0845 return getStateManager().remove<T>(this);
0846 }
0847
0848 template<typename T>
0849 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
0850 return getStateManager().set<T>(this, D);
0851 }
0852
0853 template<typename T>
0854 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
0855 typename ProgramStateTrait<T>::value_type E) const {
0856 return getStateManager().set<T>(this, K, E, get_context<T>());
0857 }
0858
0859 template<typename T>
0860 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
0861 typename ProgramStateTrait<T>::value_type E,
0862 typename ProgramStateTrait<T>::context_type C) const {
0863 return getStateManager().set<T>(this, K, E, C);
0864 }
0865
0866 template <typename CB>
0867 CB ProgramState::scanReachableSymbols(SVal val) const {
0868 CB cb(this);
0869 scanReachableSymbols(val, cb);
0870 return cb;
0871 }
0872
0873 template <typename CB>
0874 CB ProgramState::scanReachableSymbols(
0875 llvm::iterator_range<region_iterator> Reachable) const {
0876 CB cb(this);
0877 scanReachableSymbols(Reachable, cb);
0878 return cb;
0879 }
0880
0881
0882
0883
0884
0885 class ScanReachableSymbols {
0886 typedef llvm::DenseSet<const void*> VisitedItems;
0887
0888 VisitedItems visited;
0889 ProgramStateRef state;
0890 SymbolVisitor &visitor;
0891 public:
0892 ScanReachableSymbols(ProgramStateRef st, SymbolVisitor &v)
0893 : state(std::move(st)), visitor(v) {}
0894
0895 bool scan(nonloc::LazyCompoundVal val);
0896 bool scan(nonloc::CompoundVal val);
0897 bool scan(SVal val);
0898 bool scan(const MemRegion *R);
0899 bool scan(const SymExpr *sym);
0900 };
0901
0902 }
0903
0904 }
0905
0906 #endif