<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Richard,<div class=""><br class=""></div><div class="">Thanks for your reply!<br class=""><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">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.</div></div></div></div></div></blockquote><div><br class=""></div>Right, sure, but I don’t have a convenient way to find that DecompositionDecl from a given BindingDecl,</div><div>and sometimes I need to act based on the BindingDecl alone.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">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.</div></div></div></div></div></blockquote><div><br class=""></div><div>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.</div><div>Given a statement, the analyzer processes it just based on AST.</div><div>What would “expand” mean here? Defining a kind of intermediate representation the analyzer operates on?</div><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word; line-break: after-white-space;" class=""><div class=""><div class="">In my understanding, clang itself has the same problem with strange special cases like not being able to capture a binding in a lambda.</div></div></div></blockquote><div class=""><br class=""></div><div class="">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.</div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word; line-break: after-white-space;" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">The intended operational semantics are that when you see a DeclRefExpr naming a BindingDecl, you evaluate its associated subexpression.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">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.</div><div class="">Also to evaluate all its subexpressions we need to introduce special casing for BindingDecl’s, as they are not VarDecl’s anymore.</div></div></div></blockquote><div class=""><br class=""></div><div class="">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.<br class=""></div></div></div></div></div></blockquote><div><br class=""></div><div>Yes, yes, of course I understand that Clang implements the standard correctly.</div><div>I was just saying that the wording of c++17 standard is a bit unfortunate for us,</div><div>since it means a lot of special casing.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Simple example:</div><div class=""><br class=""></div><div class="">struct A { int x, y; };</div><div class=""><br class=""></div><div class="">void f(A a) {</div><div class="">  auto [v, w] = a;</div><div class="">  use(v, w);</div><div class="">}</div><div class=""><br class=""></div><div class="">This gives you a DecompositionDecl, which is a kind of VarDecl, of type A, initialized with 'a'. Let's call that 'e'.</div><div class="">It also gives you two BindingDecls, which are symbolic names for the expressions 'e.x' and 'e.y'.</div><div class="">So the evaluation semantics of the above function are as if you wrote:</div><div class=""><br class=""></div><div class="">void f(A a) {</div><div class="">  A e = a;</div><div class="">  use(e.x, e.y);</div><div class="">}</div></div></div></div></div></blockquote><div><br class=""></div>Right, thanks for the clarification!</div><div>In my mind, the final version was equivalent to</div><div><br class=""></div><div>void f(A a) {</div><div>  auto &v = a.x;</div><div>  auto &w = a.y;</div><div>  use(v, w);</div><div>}</div><div><br class=""></div><div>but I guess that’s not the case.</div><div>Was a different model chosen in the standard due to performance considerations?</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">That's what the CFG for the above function should represent.</div></div></div></div></div></blockquote><div><br class=""></div><div>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).</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> 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'.</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word; line-break: after-white-space;" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">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.</div><div class=""><br class=""></div><div class="">(Perhaps the static analyzer needs more than that in order to produce more user-friendly diagnostics?)</div></div></div></div></div></blockquote><div class=""><br class=""></div></span>We are not even there yet for structured bindings, just trying to make the analyzer understand them.<br class=""><br class=""></div><div class=""><br class=""></div><br class=""></div><br class="">______________________________<wbr class="">_________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-dev</a></blockquote></div></div></div></div></blockquote></div><br class=""></div></body></html>