[PATCH] c++: Allow constexpr references to non-static vars [PR100976]

Jason Merrill jason@redhat.com
Sat Jul 17 21:40:08 GMT 2021


On 7/16/21 1:44 PM, Marek Polacek wrote:
> On Fri, Jul 16, 2021 at 12:53:05PM -0400, Jason Merrill wrote:
>> On 7/15/21 5:14 PM, Marek Polacek wrote:
>>> The combination of DR 2481 and DR 2126 should allow us to do
>>>
>>>     void f()
>>>     {
>>>       constexpr const int &r = 42;
>>>       static_assert(r == 42);
>>>     }
>>>
>>> because [expr.const]/4.7 now says that "a temporary object of
>>> non-volatile const-qualified literal type whose lifetime is extended to
>>> that of a variable that is usable in constant expressions" is usable in
>>> a constant expression.
>>>
>>> I think the temporary is supposed to be const-qualified, because Core 2481
>>> says so.  I was happy to find out that we already mark the temporary as
>>> const + constexpr in set_up_extended_ref_temp.
>>>
>>> But that wasn't enough to make the test above work: references are
>>> traditionally implemented as pointers, so the temporary object will be
>>> (const int &)&D.1234, and verify_constant -> reduced_constant_expression_p
>>> -> initializer_constant_valid_p_1 doesn't think that's OK -- and rightly
>>> so -- the address of a local variable certainly isn't constant
>>
>> Hmm.  I'm very sorry, I'm afraid I've steered you wrong repeatedly, and this
>> is the problem with my testcase above and in the PR.
> 
> No worries, in fact, I'm glad we don't have to introduce gross hacks into the
> front end!
> 
>> Making that temporary usable in constant expressions doesn't make it a valid
>> initializer for the constexpr reference, because it is still not a
>> "permitted result of a constant expression"; [expr.const]/11 still says that
>> such an entity must have static storage duration.
> 
> Indeed: "...if it is an object with static storage duration..."
> And I never scrolled down to see that when looking at [expr.const] when looking
> into this...
> 
>> So the above is only valid if the reference has static storage duration.
> 
> Is there anything we need to do to resolve DR 2481 and DR 2126, then?  Besides
> adding this test:
> 
>    typedef const int CI[3];
>    constexpr CI &ci = CI{11, 22, 33};
>    static_assert(ci[1] == 22, "");

It seems not.

Jason



More information about the Gcc-patches mailing list