[LLVMbugs] [Bug 19643] accessing an element of `constexpr static array` inaccurately treated as ODR-usage
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Fri May 2 13:45:24 PDT 2014
http://llvm.org/bugs/show_bug.cgi?id=19643
Filip Roséen <filip.roseen at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |REOPENED
Resolution|INVALID |---
--- Comment #2 from Filip Roséen <filip.roseen at gmail.com> ---
(In reply to comment #1)
> Sorry, that's not correct.
>
> We have the expression A::a[0]. Let's walk through 3.2/3:
>
> "A variable x [A::a] whose name appears as a potentially-evaluated
> expression ex [the id-expression A::a, check] is odr-used unless
>
> applying the lvalue-to-rvalue conversion to x yields a constant expression
> [it does]
> that does not invoke any non-trivial functions [it does not] and,
> if x is an object [it is],
> ex is an element of the set of potential results of an expression e,
> where either the lvalue-to-rvalue conversion is applied to e, or e is a
> discarded-value expression."
>
> So: what possible values of 'e' are there? The set of potential results of
> an expression is a set of subexpressions of the expression, so we only need
> to consider expressions of which 'ex' is a subexpression. Those are:
>
> A::a
> A::a[0]
>
> Of these, the lvalue-to-rvalue conversion is *not* applied immediately to
> A::a, so we only consider A::a[0]. Per 3.2/2, the set of potential results
> of A::a[0] is empty, so A::a is odr-used by this expression.
>
>
> Now, you could argue that we first rewrite A::a[0] to *(A::a + 0). But that
> changes nothing: the possible values of e are then
>
> A::a
> A::a + 0
> (A::a + 0)
> *(A::a + 0)
>
> Of these, only the fourth has an lvalue-to-rvalue conversion applied to it,
> and again, 3.2/2 says that the set of potential results of *(A::a + 0) is
> empty.
(In reply to comment #1)
> Sorry, that's not correct.
>
> We have the expression A::a[0]. Let's walk through 3.2/3:
>
> "A variable x [A::a] whose name appears as a potentially-evaluated
> expression ex [the id-expression A::a, check] is odr-used unless
>
> applying the lvalue-to-rvalue conversion to x yields a constant expression
> [it does]
> that does not invoke any non-trivial functions [it does not] and,
> if x is an object [it is],
> ex is an element of the set of potential results of an expression e,
> where either the lvalue-to-rvalue conversion is applied to e, or e is a
> discarded-value expression."
>
> So: what possible values of 'e' are there? The set of potential results of
> an expression is a set of subexpressions of the expression, so we only need
> to consider expressions of which 'ex' is a subexpression. Those are:
>
> A::a
> A::a[0]
>
> Of these, the lvalue-to-rvalue conversion is *not* applied immediately to
> A::a, so we only consider A::a[0]. Per 3.2/2, the set of potential results
> of A::a[0] is empty, so A::a is odr-used by this expression.
>
>
> Now, you could argue that we first rewrite A::a[0] to *(A::a + 0). But that
> changes nothing: the possible values of e are then
>
> A::a
> A::a + 0
> (A::a + 0)
> *(A::a + 0)
>
> Of these, only the fourth has an lvalue-to-rvalue conversion applied to it,
> and again, 3.2/2 says that the set of potential results of *(A::a + 0) is
> empty.
You make some very convincing points, and now I'm asking mostly out of
curiosity to why this is ODR-usage.
Having the same snippet as earlier both `gcc` and `clang` accepts `int
b[A::a[0]];`. `A::a[0]` is an expression that must be evaluated during
translation and both evaluates it to `1`, so far so good.
When initializing `int value` with `A::a[0]` we are not in a context which
mandates evaluation during translation, which certainly change things.
[basic.def.odr]p2 states that something is ODR-used unless it is an object that
satisfies the requirements to appear in a constant-expression, and the
lvalue-to-rvalue conversion happens immediately.
When I was reasoning about this, with help of others interested in the subject,
we concluded that because of [expr.const]p2, that states that a glvalue of
literal type (which `A::a` is) that refers to a non-volatile const object (once
again, true) or that refers to a subobject of such an object (`A::a[0]`), this
was not an ODR-use.
I've read your explanation a few times but I still don't understand it. I do
however understand if you got other things to attend to, but I'm very
interested to understanding why this is ODR-usage.
Thanks.
----------------------------------------------------------
[ Note: originally I thought it was, but then I spent time thinking about it
and.. changed my mind ]
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20140502/2ea72a60/attachment.html>
More information about the llvm-bugs
mailing list