================ @@ -490,6 +491,47 @@ SVal SValBuilder::evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc, llvm_unreachable("Unexpected unary operator"); } +namespace { +/// Iterate through to store to find the actual value this LazyCompoundVal +/// corresponds to. Further reading is in LazyCompoundVal's docs. +struct LazyHandler : public StoreManager::BindingsHandler { + nonloc::LazyCompoundVal l; + std::optional<SVal> &Ret; + + LazyHandler(nonloc::LazyCompoundVal l, std::optional<SVal> &Ret) + : l(l), Ret(Ret) {} + + virtual bool HandleBinding(StoreManager &SMgr, Store Store, + const MemRegion *Region, SVal Val) override { + if (const MemRegion *MR = Val.getAsRegion()) { + if (MR->isSubRegionOf(l.getRegion()) && MR != l.getAsRegion()) { + Ret = Val; + return false; + } + } + return true; + } +}; +} // namespace + +/// Find the actual value behind a LazyCompoundVal. May return none if the +/// query fails, or only finds another LazyCompoundVal (e.g. circular +/// reference). +static std::optional<SVal> extractActualValueFrom(ProgramStateRef State, + nonloc::LazyCompoundVal L) { + std::optional<SVal> Ret; + LazyHandler handler{L, Ret}; + State->getStateManager().getStoreManager().iterBindings(State->getStore(), + handler); + if (Ret) { + std::optional<SVal> RVal = Ret = State->getSVal(Ret->getAsRegion()); + // If our best efforts lead us back to another LazyCompoundValue, give up. + if (Ret == RVal) + return {}; ---------------- NagyDonat wrote:
Something is fishy here -- after `RVal = Ret` the condition `Ret == RVal` should always be true. https://github.com/llvm/llvm-project/pull/106982 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits