Bug 100976

Summary: [C++23] Make constexpr reference temp constexpr
Product: gcc Reporter: Jason Merrill <jason>
Component: c++Assignee: Marek Polacek <mpolacek>
Status: RESOLVED WORKSFORME    
Severity: normal CC: mpolacek, webrown.cpp
Priority: P3    
Version: 12.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2021-06-08 00:00:00
Bug Depends on:    
Bug Blocks: 98940    

Description Jason Merrill 2021-06-08 17:46:11 UTC
https://wg21.link/cwg2481
Comment 1 Jason Merrill 2021-06-08 18:45:22 UTC
  constexpr const int &r = 42;
  static_assert(r == 42);
Comment 2 Jason Merrill 2021-06-08 20:51:35 UTC
Or rather,

int main()
{
  constexpr const int &r = 42;
  static_assert(r == 42); // { dg-bogus "" }
}

[expr.const]/4.7 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.
Comment 3 Marek Polacek 2021-07-01 20:09:58 UTC
(In reply to Jason Merrill from comment #2)
> Or rather,
> 
> int main()
> {
>   constexpr const int &r = 42;
>   static_assert(r == 42); // { dg-bogus "" }
> }
> 
> [expr.const]/4.7 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.

This was actually CWG 2126 which we don't seem to fully implement:

struct A { int n; };

const A &a = {1};              // const temporary
A &b = (A &)(const A &)A{1};   // const temporary
A &&c = (A &&)(const A &)A{1}; // const temporary

static_assert(a.n == 1, "");
static_assert(b.n == 1, "");
static_assert(c.n == 1, "");
Comment 4 Marek Polacek 2021-07-19 13:59:55 UTC
Turned out we already implement CWG 2481.  If anyone has a test for something we don't handle, please open a PR.