[cfe-commits] [PATCH] Expressions have lvalues and rvalues
Ted Kremenek
kremenek at apple.com
Sat Oct 11 20:58:28 PDT 2008
On Oct 11, 2008, at 8:16 PM, Zhongxing Xu wrote:
> On Sun, Oct 12, 2008 at 11:14 AM, Zhongxing Xu
> <xuzhongxing at gmail.com> wrote:
> So how about calling them Address and NonAddress? This would get rid
> of the dangerous similarity between LVal and LValue.
>
> Sebastian
>
> What about LocVal and NonLocVal?
>
>
> How about:
>
> RVal => AVal (abstract value)
> LVal => LocVal (location value)
> NonLVal => NonLocVal (non-location value)
Sounds good, other than "AVal" should probably be something like
"AbstractVal", since we don't use it that much and the "A" doesn't
really mean anything unless you look at the comments (can't use "Abs"
because someone might think it means "absolute"). ExprVal is also a
possibility (see later in this email for more comments).
Getting back to the points both you and Sebastian made, I'm wondering
if there is any advantage with changing the implementation of RVal/
LVal to be something much closer to the way C++ reasons about these
concepts. This might in the long run clean up a whole bunch of
things, especially as we add more support for C++.
I don't have any concrete ideas, but there exists a lot of redundancy
between the lval and nonlval classes. For example, lval::ConcreteInt
and nonlval::ConcreteInt are essentially the same class representing
the same data. The same goes for lval::SymbolVal and
nonlval::SymbolVal. The distinction between the lval:: and nonlval::
versions is purely context, which is often redundant since one often
(always?) knows the current context and how these values should be
interpreted. If we modeled lvalues in the sense that Sebastian
articulated, we would probably only have a handful of classes:
lval::MemoryRegion, lval::Undefined, lval::Unknown, and that's
probably it. We would have an nonlval::MemoryRegion (or rather
rval::MemoryRegion if we want nonlval to represent rvalues), but
symbols, integers, etc., would always be rvalues.
One thing about this is that it makes the transfer function structure
basically fall out from what's in the C/C++ standards. For example,
the '*' operator essentially has the following type signature:
* : rval -> lval
Similarly, references to variables and the '&' operator could be
represented as follows:
variable reference: (declrefexpr) -> lval
& : lval -> rval (with the rval being an rval::MemoryRegion)
In contexts where an lval is used as an rval, we have an implicit
conversion (as stated in the C++ standard). Such implicit
conversations would be represented by a transfer function, which cause
a new state and ExplodedNode to be created to represent the effect of
this conversion. For example, an implicit conversion from an lval to
rval could result in a value load (e.g., EvalLoad, which would have
the type signature lval -> rval).
Zhongxing: In a roundabout way, I think your patch (which I have now
looked at) is trying to resolve some of the confusion between rvalues
and lvalues, but I'm wondering if the distinction between rvalues and
lvalues really should happen in the Store. This of course is a
naturally progression of the current design, but after Sebastian's
points I'm wondering if that is the right direction. In my mind, all
the store should care about is the mapping between regions and
abstract values (a notion that has nothing to do with LVal and
NonLval) and the mapping between variable names and the their
regions. These are pretty clean interfaces that don't have to get
tangled with the notion of rvalues and lvalues, which seem more
related to how GRExprEngine should handle individual expressions.
In a nutshell, I'm wondering if we should do the following:
1) Change "RVal" to "ExprVal" (representing the value of an
expression). ExprVal makes it clear that these objects represent the
evaluation of an expression.
2) Change 'nonlval::" to "rval::", and remove most of the lval classes
such as lval::SymbolicInt and lval::ConcreteInt. Add an
"rval::MemoryRegion" class that mirrors "lval::MemoryRegion".
3) Change GRExprEngine to reason about rvals (rvalues) and lvals
(lvalues) in the same way the C++ standard does. This is a big task,
but I think it is mainly code restructuring. Loads would be handled
as transfer functions (i.e., EvalLoad) doing the implicit conversions
between lvals -> rvals.
I see three advantages of these changes:
1) The structure of GRExpEngine more closely reflects the semantics of
C/C++ as given by the respective standards. This will make the
analyzer much easier to extend potential C++ 0X features, such as
rvalue references, as the design of how to implement these features in
GRExprEngine should be more obvious and intuitive. This should also
address Sebastian's original concerns (and the concerns of those with
a similar perspective). It will also make it much clearer for those
new to the libAnalysis/GRExprEngine about what is going on.
2) There will probably be a significant code reduction/simplification
in many cases, as the code duplication for lval::SymbolicVal and
nonlval::SymbolicVal, lval::ConcreteInt and nonlval::ConcreteInt, gets
eradicated.
3) The meaning/purpose of LVal/RVal/NonLval (whatever we call them)
will be made clear: they exist purely for GRExprEngine to correctly
implement/call the right transfer functions. The Environment class
will be a mapping from "Expr* -> ExprVal", and implementations of the
Store won't care about ExprVals at all; just regions and the values
they map to. I see this as a being a huge conceptually cleanup;
implementations of Store won't have to reason about rvalues and
lvalues at all, just locations and the values stored at those
locations. The distinction between rvalues and lvalues is something
that C and C++ language lawyers should care about, but people wishing
to model the heap in a particular implementation of store shouldn't
have to care about these things at all.
What do you think? It seems like important changes like this (if we
make them) should get in before the system gets any larger and more
complex. Note that I don't think these changes are necessarily the
best ones; I'm just very much interested in discussing whether or not
the overall design of RVals/Lvals needs to be changed.
Ted
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20081011/f30e57f2/attachment.html>
More information about the cfe-commits
mailing list