<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/54109>54109</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            constinit should not tie to constant evaluation
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          zhihaoy
      </td>
    </tr>
</table>

<pre>
    `constinit` ensures static initialization (the compliment of dynamic initialization, according to [[dcl.constinit]/2](http://eel.is/c++draft/dcl.constinit#2)) rather than requiring constant-initialization. According to [[basic.start.static]/3.2](http://eel.is/c++draft/basic.start.static#3.2), an implementation is permitted to perform more static initializations, and that's what Clang is doing. But this behavior is not reflected in `constinit`. The following code doesn't compile:

```cpp
struct entity {
  static void call(entity *, int);
};

typedef void call_fn(void *, int);

template <class T> struct vtable {
  call_fn *call;
};

template <class T> inline constinit vtable<T> vtable_for{(call_fn *)T::call};

struct wrapper {
  vtable<entity> *vt = &vtable_for<entity>;
  void *data;
};
```

```
b.cc:11:48: error: variable does not have a constant initializer
template <class T> inline constinit vtable<T>  vtable_for{(call_fn *)T::call};
                                               ^         ~~~~~~~~~~~~~~~~~~~~
b.cc:14:25: note: in instantiation of variable template specialization 'vtable_for<entity>' requested here
  vtable<entity> *vt = &vtable_for<entity>;
                        ^
b.cc:11:27: note: required by 'constinit' specifier here
template <class T> inline constinit vtable<T>  vtable_for{(call_fn *)T::call};
                          ^~~~~~~~~
b.cc:11:59: note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
template <class T> inline constinit vtable<T>  vtable_for{(call_fn *)T::call};
                                                          ^
1 error generated.
```

The code compiles fine in GCC 10.2 and MSVC 19.29, C++20 modes.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVk2TozgM_TXkohoKTAjkwKE73bOnPW3XXrscLIK3HMzYJr2ZX7-ynYSkOj01H3uYlMuxwJaenmSJrRbHJlllrR6sk4N0tAYc7GTQgnXcyRb8Y8mV_EqSHiBhtesRWr0fldzj4EB3II4D37_bm7AN8LbVRshhB05DUj7SEK1KZ4PlU8I-s_BX986NSfFAD2ggqlRaWrQJe6QhDO8cibfHWcEStqYBhhMuA67nAxj8MknjrYadfHCfbqGl8PAe2JZb2aa03bg0Oh_RFemP4LujhRVehYdJhAwgiTr01EVGpYURzV46h8KDIaHTZg97bfB-EGxUJLyzZLKy8EYL2ChO7pA6ocmvFB4nRztI3mLPD1Ib_27QjujpFLbenKSA3oY_hRcKb6eV0m-RQIGkEC2Fs3Ih7lKhZyF7SrLzvMriaMcxPrHOTK2jXHLSHSGpHuNjODt00FJAy5UiWs-b2IP3Sw7OU1WcTiTV07wOszuOKLCbVbx2hK0O4gc64jkk3rlDSIpNq7i18JIUz3BCenB8q_Aa6Um11xmAfgPRfc1yUHJAuLB7skGbwusovVKsvVFWX9kj8C-e4iJafmfwhPnN8JGy5Rr0xUQk1dshfQdH0J5otboyerXnoh7gTKPgjt93-RzruwkQxW3atgQ-z2la1jQBGuNNPsCBGxmY9jkVspFyE4Ffbuqc62h-hd6f4xd-7JeUz_O6ev75cUPbkiZWeraIH3_X_D2VkR4ZiwYV3QuTF37siO1Nqa4-CDerQolE62sAVU3839LnQ5reJwarrj2MJZvgbH0lqK4qfBX96iRl-oz190gK79h3hdQ7XK6vHW65daGAnwu-hdhYhwMa66u8DzInYqiaoRkNutdw5lTEua_QsYRfXR78lzZaf_x3ouk7rlFUkcdCATsckBo6ivQbRecl0CXw3JQsdN4pIuSPzQbyLGWhSf75198krdPYfzexW7OM-qtAmy5EU4h1seYLSmaFzUyJ7fWkRODaSfSdeWb5wNUULtliMqrx3wX28mGwk66fKO56T4JSh_Pfp9Hof6jtkiitpctHi3KZZ-tF3wixKrEU1TLHLCvKdVnWy7rNW8aKPM9EsVB8i8o2_kOFsQHfIKigNX2ZLGTDMuZHnZX5ulylosxxuarqou6KruN5ssxwz6VKPY5Um93CNAHSdtpZeqmkdXZ-SWkidwNiMEf6-eR6bZqvvey5Pi6C6SZA_w8QxhbM">