================ @@ -2605,9 +2608,43 @@ RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B, return NewB; } +std::optional<SVal> +RegionStoreManager::getUniqueDefaultBinding(nonloc::LazyCompoundVal LCV) const { + const MemRegion *BaseR = LCV.getRegion(); + + // We only handle base regions. + if (BaseR != BaseR->getBaseRegion()) + return std::nullopt; + + const auto *Cluster = getRegionBindings(LCV.getStore()).lookup(BaseR); + if (!Cluster || !llvm::hasSingleElement(*Cluster)) + return std::nullopt; + + const auto [Key, Value] = *Cluster->begin(); + return Key.isDirect() ? std::optional<SVal>{} : Value; +} + std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallStruct( RegionBindingsConstRef B, const TypedValueRegion *R, const RecordDecl *RD, nonloc::LazyCompoundVal LCV) { + // If we try to copy a Conjured value representing the value of the whole + // struct, don't try to element-wise copy each field. + // That would unnecessarily bind Derived symbols slicing off the subregion for + // the field from the whole Conjured symbol. + // + // struct Window { int width; int height; }; + // Window getWindow(); <-- opaque fn. + // Window w = getWindow(); <-- conjures a new Window. + // Window w2 = w; <-- trivial copy "w", calling "tryBindSmallStruct" + // + // We should not end up with a new Store for "w2" like this: + // Direct [ 0..31]: Derived{Conj{}, w.width} + // Direct [32..63]: Derived{Conj{}, w.height} + // Instead, we should just bind that Conjured value instead. + if (auto Val = getUniqueDefaultBinding(LCV)) { ---------------- NagyDonat wrote:
As you simplified the parametrization of this function, now you can replace `auto` with the explicit type :slightly_smiling_face: (if you want). https://github.com/llvm/llvm-project/pull/115917 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits