[cfe-dev] Getting DecompositionDecl from BindingDecl

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Fri Mar 30 20:49:21 PDT 2018


On Fri, 30 Mar 2018, 20:22 George Karpenkov via cfe-dev, <
cfe-dev at lists.llvm.org> wrote:

> Hi Richard,
>
> Thanks for your reply!
>
> 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.
>
>
> Right, sure, but I don’t have a convenient way to find that
> DecompositionDecl from a given BindingDecl,
> and sometimes I need to act based on the BindingDecl alone.
>

Can you give an example?

> 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.
>
>
> Could you clarify what you mean? For the analyzer, the CFG is just used to
> model the control flow, and to separate it into statements.
> Given a statement, the analyzer processes it just based on AST.
> What would “expand” mean here? Defining a kind of intermediate
> representation the analyzer operates on?
>

Yes, see below.

>
>
>> 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.
>
>
> Yes, yes, of course I understand that Clang implements the standard
> correctly.
> I was just saying that the wording of c++17 standard is a bit unfortunate
> for us,
> since it means a lot of special casing.
>
>
> 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);
> }
>
>
> Right, thanks for the clarification!
> In my mind, the final version was equivalent to
>
> void f(A a) {
>   auto &v = a.x;
>   auto &w = a.y;
>   use(v, w);
> }
>
> but I guess that’s not the case.
> Was a different model chosen in the standard due to performance
> considerations?
>

It was chosen because it matches the semantic model desired by the
designers of the feature. For example, you can't handle bitfields if you
model structured bindings as reference variables.

This was a somewhat controversial decision, but it doesn't look like it's
going to be reversed.

> That's what the CFG for the above function should represent.
>
>
> Sorry, I’m not sure what do you mean here: from my understanding, CFG does
> not transform AST inside statements (apart from maybe tiny syntactic
> things).
>

IIRC, the CFG expands CXXDefaultArgExprs and CXXDefaultInitExprs; this case
is analogous to those.

> 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
>
>
> _______________________________________________
> 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/20180331/8ea644d6/attachment.html>


More information about the cfe-dev mailing list