[cfe-dev] Incorrect result from DeclRefExpr::refersToEnclosingVariableCapture?

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Wed Oct 21 18:16:23 PDT 2015


On Wed, Oct 21, 2015 at 4:08 PM, James Dennett via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Wed, Oct 21, 2015 at 11:14 AM, Tim Prince via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>> Hi everyone,
>>
>> We've been working on upgrading our frontend from clang 3.4 to 3.7 and
>> have run
>> into an issue where 'DeclRefExpr::refersToEnclosingVariableOrCapture'
>> seems to be
>> returning the incorrect result. Here's a test case:
>>
>>   int fn1() {
>>     const int i = 0;
>>     return [] { return i; }();
>>   }
>>
>> Calling 'refersToEnclosingVariableOrCapture' on the 'DeclRefExpr' for 'i'
>> within
>> the lambda body yields false. In clang 3.4, the equivalent
>> 'refersToCapturedVariable'
>> method yields true. It looks this behavior was probably introduced by
>> r224323,
>> which changed 'Sema::BuildDeclRefExpr' to determine this via
>> 'tryCaptureVariable'.
>>
>>
> That's an interesting case.  `i` is a compile-time constant expression
> there, so there's
> no ODR-use of the variable, hence it's not captured.  I don't know what
> that should
> imply for refersToEnclosingVariableOrCapture; the specification is a touch
> vague.
>

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.


> So with that background, I have a few questions:
>>
>> - Is this code even valid? It seems like it shouldn't be since there's no
>>   capture-default or capture-list, but both clang and GCC accept it.
>>
>
> I believe it is, as only the value of the constant expression is used.
>
>
>> - Assuming the code is valid, is this a bug in clang?
>>
>
> I don't know.
>

It is; we don't yet implement the new "or e is a discarded-value
expression" wording in [basic.def.odr]/2.


> - If not, is there some other way to detect when a DeclRefExpr in a lambda
>> body
>>   refers to a declaration from the enclosing scope?
>>
>
> 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.
>

You could check the DeclContext of the variable.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151021/122bb6b6/attachment.html>


More information about the cfe-dev mailing list