diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-07-27 23:34:35 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-10-23 18:26:01 +0000 |
commit | 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch) | |
tree | 6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp | |
parent | 6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff) | |
parent | ac9a064cb179f3425b310fa2847f8764ac970a4d (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index f12f1a5ac970..f82cd944750a 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -226,6 +226,20 @@ ProgramStateRef ProgramState::killBinding(Loc LV) const { return makeWithStore(newStore); } +/// SymbolicRegions are expected to be wrapped by an ElementRegion as a +/// canonical representation. As a canonical representation, SymbolicRegions +/// should be wrapped by ElementRegions before getting a FieldRegion. +/// See f8643a9b31c4029942f67d4534c9139b45173504 why. +SVal ProgramState::wrapSymbolicRegion(SVal Val) const { + const auto *BaseReg = dyn_cast_or_null<SymbolicRegion>(Val.getAsRegion()); + if (!BaseReg) + return Val; + + StoreManager &SM = getStateManager().getStoreManager(); + QualType ElemTy = BaseReg->getPointeeStaticType(); + return loc::MemRegionVal{SM.GetElementZeroRegion(BaseReg, ElemTy)}; +} + ProgramStateRef ProgramState::enterStackFrame(const CallEvent &Call, const StackFrameContext *CalleeCtx) const { @@ -451,6 +465,24 @@ void ProgramState::setStore(const StoreRef &newStore) { store = newStoreStore; } +SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const { + Base = wrapSymbolicRegion(Base); + return getStateManager().StoreMgr->getLValueField(D, Base); +} + +SVal ProgramState::getLValue(const IndirectFieldDecl *D, SVal Base) const { + StoreManager &SM = *getStateManager().StoreMgr; + Base = wrapSymbolicRegion(Base); + + // FIXME: This should work with `SM.getLValueField(D->getAnonField(), Base)`, + // but that would break some tests. There is probably a bug somewhere that it + // would expose. + for (const auto *I : D->chain()) { + Base = SM.getLValueField(cast<FieldDecl>(I), Base); + } + return Base; +} + //===----------------------------------------------------------------------===// // State pretty-printing. //===----------------------------------------------------------------------===// |