[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