================ @@ -346,6 +352,39 @@ class CompoundVal : public NonLoc { static bool classof(SVal V) { return V.getKind() == CompoundValKind; } }; +/// The simplest example of a concrete compound value is nonloc::CompoundVal, +/// which represents a concrete r-value of an initializer-list or a string. +/// Internally, it contains an llvm::ImmutableList of SVal's stored inside the +/// literal. +/// +/// However, there is another compound value used in the analyzer, which appears +/// much more often during analysis, which is nonloc::LazyCompoundVal. This +/// value is an r-value that represents a snapshot of any structure "as a whole" +/// at a given moment during the analysis. Such value is already quite far from +/// being re- ferred to as "concrete", as many fields inside it would be unknown +/// or symbolic. nonloc::LazyCompoundVal operates by storing two things: +/// * a reference to the TypedValueRegion being snapshotted (yes, it is always +/// typed), and also +/// * a copy of the whole Store object, obtained from the ProgramState in ---------------- haoNoQ wrote:
> Is it truly a copy of the store object? This seems to contradict the "is a > very cheap operation" line in the next paragraph...? Yes! Congratulations, now you understand functional programming. Because the Store is an ImmutableMap, it is uniquely identified by a single pointer to the unique, carefully deduplicated instance of that map. The cost of a copy is the cost of a single 64-bit assignment. It's literally cheaper to copy the entire thing than to copy a portion of it, because a portion would be a different object, which we haven't created yet. It's like copy on write, except, the write isn't supported in the first place. Of course the best part is that the "modification" is also cheap. Instead of modifying a map (and ruining everyone's "copy"), we just describe the modified map as essentially "the same as the other map except this one key has a different value". Which is also very quick to describe. Though, we still need to organize them into AVL trees for both fast lookup and fast deduplication. So it's not as straightforward as immutable lists which all naturally "grow on trees". But still, yes, all these operations are cheap, and this is how when you print the exploded graph it prints you every state, every store, behind every node. Because it doesn't cost anything extra to keep the copies around. https://github.com/llvm/llvm-project/pull/97407 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits