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_STORE_H
0014 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
0015
0016 #include "clang/AST/Type.h"
0017 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
0018 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
0019 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
0020 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
0021 #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
0022 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
0023 #include "clang/Basic/LLVM.h"
0024 #include "llvm/ADT/ArrayRef.h"
0025 #include "llvm/ADT/DenseSet.h"
0026 #include "llvm/ADT/SmallVector.h"
0027 #include <cassert>
0028 #include <cstdint>
0029 #include <memory>
0030 #include <optional>
0031
0032 namespace clang {
0033
0034 class ASTContext;
0035 class CastExpr;
0036 class CompoundLiteralExpr;
0037 class CXXBasePath;
0038 class Decl;
0039 class Expr;
0040 class LocationContext;
0041 class ObjCIvarDecl;
0042 class StackFrameContext;
0043
0044 namespace ento {
0045
0046 class CallEvent;
0047 class ProgramStateManager;
0048 class ScanReachableSymbols;
0049 class SymbolReaper;
0050
0051 using InvalidatedSymbols = llvm::DenseSet<SymbolRef>;
0052
0053 class StoreManager {
0054 protected:
0055 SValBuilder &svalBuilder;
0056 ProgramStateManager &StateMgr;
0057
0058
0059 MemRegionManager &MRMgr;
0060 ASTContext &Ctx;
0061
0062 StoreManager(ProgramStateManager &stateMgr);
0063
0064 public:
0065 virtual ~StoreManager() = default;
0066
0067
0068
0069
0070
0071
0072
0073
0074 virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 virtual std::optional<SVal> getDefaultBinding(Store store,
0087 const MemRegion *R) = 0;
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 std::optional<SVal> getDefaultBinding(nonloc::LazyCompoundVal lcv) {
0098 return getDefaultBinding(lcv.getStore(), lcv.getRegion());
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108 virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0;
0109
0110
0111
0112
0113 virtual StoreRef BindDefaultInitial(Store store, const MemRegion *R,
0114 SVal V) = 0;
0115
0116
0117
0118 virtual StoreRef BindDefaultZero(Store store, const MemRegion *R) = 0;
0119
0120
0121
0122
0123 virtual StoreRef killBinding(Store ST, Loc L) = 0;
0124
0125
0126
0127 virtual StoreRef getInitialStore(const LocationContext *InitLoc) = 0;
0128
0129
0130
0131 MemRegionManager& getRegionManager() { return MRMgr; }
0132
0133 SValBuilder& getSValBuilder() { return svalBuilder; }
0134
0135 virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
0136 return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC));
0137 }
0138
0139 Loc getLValueCompoundLiteral(const CompoundLiteralExpr *CL,
0140 const LocationContext *LC) {
0141 return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
0142 }
0143
0144 virtual SVal getLValueIvar(const ObjCIvarDecl *decl, SVal base);
0145
0146 virtual SVal getLValueField(const FieldDecl *D, SVal Base) {
0147 return getLValueFieldOrIvar(D, Base);
0148 }
0149
0150 virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base);
0151
0152
0153
0154 virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0;
0155
0156
0157
0158 SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast);
0159
0160
0161 SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath);
0162
0163
0164 SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType,
0165 bool IsVirtual);
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 std::optional<SVal> evalBaseToDerived(SVal Base, QualType DerivedPtrType);
0179
0180 const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);
0181
0182
0183
0184
0185 std::optional<const MemRegion *> castRegion(const MemRegion *region,
0186 QualType CastToTy);
0187
0188 virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
0189 SymbolReaper &SymReaper) = 0;
0190
0191 virtual bool includedInBindings(Store store,
0192 const MemRegion *region) const = 0;
0193
0194
0195
0196 virtual void incrementReferenceCount(Store store) {}
0197
0198
0199
0200
0201 virtual void decrementReferenceCount(Store store) {}
0202
0203 using InvalidatedRegions = SmallVector<const MemRegion *, 8>;
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 virtual StoreRef invalidateRegions(
0236 Store store, ArrayRef<SVal> Values, const Stmt *S, unsigned Count,
0237 const LocationContext *LCtx, const CallEvent *Call,
0238 InvalidatedSymbols &IS, RegionAndSymbolInvalidationTraits &ITraits,
0239 InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) = 0;
0240
0241
0242
0243 StoreRef enterStackFrame(Store store,
0244 const CallEvent &Call,
0245 const StackFrameContext *CalleeCtx);
0246
0247
0248
0249
0250 virtual bool scanReachableSymbols(Store S, const MemRegion *R,
0251 ScanReachableSymbols &Visitor) = 0;
0252
0253 virtual void printJson(raw_ostream &Out, Store S, const char *NL,
0254 unsigned int Space, bool IsDot) const = 0;
0255
0256 class BindingsHandler {
0257 public:
0258 virtual ~BindingsHandler();
0259
0260
0261 virtual bool HandleBinding(StoreManager& SMgr, Store store,
0262 const MemRegion *region, SVal val) = 0;
0263 };
0264
0265 class FindUniqueBinding : public BindingsHandler {
0266 SymbolRef Sym;
0267 const MemRegion* Binding = nullptr;
0268 bool First = true;
0269
0270 public:
0271 FindUniqueBinding(SymbolRef sym) : Sym(sym) {}
0272
0273 explicit operator bool() { return First && Binding; }
0274
0275 bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
0276 SVal val) override;
0277 const MemRegion *getRegion() { return Binding; }
0278 };
0279
0280
0281 virtual void iterBindings(Store store, BindingsHandler& f) = 0;
0282
0283 protected:
0284 const ElementRegion *MakeElementRegion(const SubRegion *baseRegion,
0285 QualType pointeeTy,
0286 uint64_t index = 0);
0287
0288 private:
0289 SVal getLValueFieldOrIvar(const Decl *decl, SVal base);
0290 };
0291
0292 inline StoreRef::StoreRef(Store store, StoreManager & smgr)
0293 : store(store), mgr(smgr) {
0294 if (store)
0295 mgr.incrementReferenceCount(store);
0296 }
0297
0298 inline StoreRef::StoreRef(const StoreRef &sr)
0299 : store(sr.store), mgr(sr.mgr)
0300 {
0301 if (store)
0302 mgr.incrementReferenceCount(store);
0303 }
0304
0305 inline StoreRef::~StoreRef() {
0306 if (store)
0307 mgr.decrementReferenceCount(store);
0308 }
0309
0310 inline StoreRef &StoreRef::operator=(StoreRef const &newStore) {
0311 assert(&newStore.mgr == &mgr);
0312 if (store != newStore.store) {
0313 mgr.incrementReferenceCount(newStore.store);
0314 mgr.decrementReferenceCount(store);
0315 store = newStore.getStore();
0316 }
0317 return *this;
0318 }
0319
0320
0321 std::unique_ptr<StoreManager>
0322 CreateRegionStoreManager(ProgramStateManager &StMgr);
0323
0324 }
0325
0326 }
0327
0328 #endif