[cfe-dev] Getting DecompositionDecl from BindingDecl

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Fri Mar 30 14:09:57 PDT 2018


On 30 March 2018 at 11:01, George Karpenkov via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Mar 29, 2018, at 4:37 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> On 29 March 2018 at 15:08, George Karpenkov via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>> Hi Richard,
>>
>> Thanks for your reply!
>>
>> > Can you say more about why the static analyzer might want to map from a
>> BindingDecl to a DecompositionDecl?
>>
>> One thing I couldn’t figure out is how to figure out whether a given
>> binding represents a global.
>> But turns out that for my use case turns out that somehow was not
>> required.
>
>
> I'm still not sure why you'd want to know that.
>
>
> Turns out I don’t actually need this for my specific use case.
> But in general the analyzer often has different behavior for globals, as
> analysis runs on a single translation unit,
> and has to assume that any other translation unit can do whatever it wants
> to the globals.
>

OK, but a BindingDecl isn't a global (it's not even an object, just a
symbolic name for an expression). It might represent an lvalue expression
that denotes a global, but that global will be either a DecompositionDecl
or an implicitly-introduced holding variable, both of which you can readily
identify as being globals.

> > BindingDecls should generally just be treated wrappers around some
>> lvalue expression.
>>
>> Right, yes, that unfortunately forces quite a lot of special-casing on
>> us, as suddenly in many places where we expected only a VarDecl we know get
>> a BindingDecl.
>
>
> What kind of places?
>
>
> Quite a few of them.
> E.g. in https://reviews.llvm.org/D44956 liveness analysis had to be
> re-done for binding declarations (if all BindingDecls had an underlying
> VarDecl the code change would have been around four lines instead).
> The memory handling has to be extended to introduce a special class for
> dealing with binding declarations
> (again, would have been avoided if they had an underlying VarDecl) [e.g.
> partial fix just to avoid the crash is in https://reviews.llvm.org/D44183]
>

It seems to me that the problem here is actually that the CFG is
mismodeling BindingDecls. If it expanded them to their expression, I don't
think you'd need any special handling here.


> In my understanding, clang itself has the same problem with strange
> special cases like not being able to capture a binding in a lambda.
>

You can't capture a binding in a lambda because a binding is not a
variable, per the C++ standard's rules. This is not a clang problem.

> The intended operational semantics are that when you see a DeclRefExpr
> naming a BindingDecl, you evaluate its associated subexpression.
>
>
> Right, but what we also need to do is to figure out what to do with a
> BindingDecl when we see it on its own.
> Also to evaluate all its subexpressions we need to introduce special
> casing for BindingDecl’s, as they are not VarDecl’s anymore.
>

I think you may be misunderstanding the semantic model we're using here.
BindingDecls have nothing to do with VarDecls; they're a completely
different kind of thing with completely different semantics, just like
EnumConstantDecls are a completely different kind of thing with completely
different evaluation semantics.

Simple example:

struct A { int x, y; };

void f(A a) {
  auto [v, w] = a;
  use(v, w);
}

This gives you a DecompositionDecl, which is a kind of VarDecl, of type A,
initialized with 'a'. Let's call that 'e'.
It also gives you two BindingDecls, which are symbolic names for the
expressions 'e.x' and 'e.y'.
So the evaluation semantics of the above function are as if you wrote:

void f(A a) {
  A e = a;
  use(e.x, e.y);
}

That's what the CFG for the above function should represent. The
BindingDecls should not even show up, except as sugar so that clients who
care can know that the 'e.x' expression was /written as/ 'v'.

> I'd imagine this is best modeled by generating CFG nodes for the
> subexpression on each occurrence of such a DeclRefExpr, much like (IIRC) is
> done for CXXDefaultArgExpr and CXXDefaultInitExpr. That seems like it would
> not require too many special cases elsewhere.
>
> (Perhaps the static analyzer needs more than that in order to produce more
> user-friendly diagnostics?)
>
>
> We are not even there yet for structured bindings, just trying to make the
> analyzer understand them.
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180330/6eeedec8/attachment.html>


More information about the cfe-dev mailing list