<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Oct 21, 2015 at 4:08 PM, James Dennett via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Wed, Oct 21, 2015 at 11:14 AM, Tim Prince via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi everyone,<br>
<br>
We've been working on upgrading our frontend from clang 3.4 to 3.7 and have run<br>
into an issue where 'DeclRefExpr::refersToEnclosingVariableOrCapture' seems to be<br>
returning the incorrect result. Here's a test case:<br>
<br>
int fn1() {<br>
const int i = 0;<br>
return [] { return i; }();<br>
}<br>
<br>
Calling 'refersToEnclosingVariableOrCapture' on the 'DeclRefExpr' for 'i' within<br>
the lambda body yields false. In clang 3.4, the equivalent 'refersToCapturedVariable'<br>
method yields true. It looks this behavior was probably introduced by r224323,<br>
which changed 'Sema::BuildDeclRefExpr' to determine this via 'tryCaptureVariable'.<br>
<br></blockquote><div><br></div></span><div>That's an interesting case. `i` is a compile-time constant expression there, so there's</div><div>no ODR-use of the variable, hence it's not captured. I don't know what that should</div><div>imply for refersToEnclosingVariableOrCapture; the specification is a touch vague.</div></div></div></div></blockquote><div><br></div><div>What it really means is "this DeclRefExpr is referring to a capture of this variable rather than to the variable itself". The "enclosing variable" part is for the "captured statement" feature, which models captures somewhat differently.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
So with that background, I have a few questions:<br>
<br>
- Is this code even valid? It seems like it shouldn't be since there's no<br>
capture-default or capture-list, but both clang and GCC accept it.<br></blockquote><div><br></div></span><div>I believe it is, as only the value of the constant expression is used.</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
- Assuming the code is valid, is this a bug in clang?<br></blockquote><div><br></div></span><div>I don't know.</div></div></div></div></blockquote><div><br></div><div>It is; we don't yet implement the new "or e is a discarded-value expression" wording in [basic.def.odr]/2.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
- If not, is there some other way to detect when a DeclRefExpr in a lambda body<br>
refers to a declaration from the enclosing scope?<br></blockquote><div><br></div></span><div>One way is to keep track of the enclosing lambdas, and while that's something I do in code right now (out of tree) I'd prefer to get rid of that.</div></div></div></div></blockquote><div><br></div><div>You could check the DeclContext of the variable.</div></div></div></div>