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, ""); Marek