I think you are missing a few critical pieces of the overall design.

SVals are meant to represent the semantic evaluation of expressions. They can represent things like concrete integers, symbolic integers, or memory locations (which are memory regions). They are a discriminated union of “values”, symbolic and otherwise. There is no meaning to associate a memory region back to its SVal, because that relationship doesn’t exist. An SVal is just an utterance of a value; it’s not the representative of the value itself.

In contrast, symbols are meant to represent abstract, but named, symbolic values. Symbolic values can have constraints associated with them. Symbols represent an actual (immutable) value. We might not know what its specific value is, but we can associate constraints with that value as we analyze a path. To be more concrete, suppose we have:

int foo(int x) {

int y = x * 2;

int z = x;

…

}

Let’s look at how x*2 gets evaluated. When ‘x’ is evaluated, we first construct an SVal that represents the lvalue of ‘x’, in this case it is an SVal that references the MemoryRegion for ‘x’ (more on that later). Afterwards, when we do the lvalue-to-rvalue conversion, we get a new SVal, which references the value **currently bound* to ‘x’. That value is symbolic; it’s whatever ‘x’ was bound to at the start of the function. Let’s call that symbol $0. Similarly, we evaluate the expression for ‘2’, and get an SVal that references the concrete number ‘2’. When we evaluate x2, we take the two SVals of the subexpressions, and create a new SVal that represents their multiplication (which in this case is a new symbolic value, which we might call $1). When we evaluate the assignment to ‘y’, we again compute its lvalue (a MemRegion), and then bind the SVal for the RHS (which references the symbolic value $1) to the MemRegion in the symbolic store.

The second line is similar. When we evaluate ‘x’ again, we do the same dance, and have an SVal that references $0. That SVal isn’t malloc’ed (with a persistent address), it is just a C++ value object. Think of it as just a smart pointer, referencing the real values. Two SVals might reference the same underlying values.

To clarify, a MemRegion is similar to a symbol. It is used to provide a lexicon of how to describe abstract memory. Regions can layer on top of other regions, providing a layered description of how to describe memory. For example, a struct object on the stack might be represented by a VarRegion, but a FieldRegion which is a subregion of the VarRegion could be used to represent the memory associated with a specific field of that object.

Stepping back, from this perspective, there is no inherit association between a MemRegion and an SVal. An SVal might reference a MemRegion, and an SVal might represent the value bound to a MemRegion in the symbolic store, but there is a many-to-one relationship from SVals (which are just value references) to any given MemRegion.

So how do we represent symbolic memory regions? That’s what SymbolicRegion is for. It is a MemRegion that has an associated symbol. Since the symbol is unique and has a unique name, that symbol names the region.

To summarize, MemRegions are unique names for blocks of memory. Symbols are unique names for abstract symbolic values. Some MemRegions represents abstract symbolic chunks of memory, and thus are also based on symbols. SVals are just references to values, and can reference either MemRegions, Symbols, or concrete values (e.g., the number 1).

So what about extents? Extents are just symbolic values as well. We also have various mechanisms to relate symbols to other symbols. Indeed, we already have SymbolExtent, which can be used to represent the associated length of a SymbolicRegion. By using symbols to represent extents of symbolic regions, we employ the same constraint management logic for extents that we do for any other symbolic value.

We really do have all the pieces in place. We already have symbolic extents. The idea might need to be refined in its implementation, but everything we need is already basically there.