<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/58682>58682</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang] template decltype(auto) substitution failure for non-constinit static lval ref argument
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
willwray
</td>
</tr>
</table>
<pre>
Rejects valid template specialization with a substitution failure.
E.g. given a class template with a C++17 `decltype(auto)` placeholder parameter
and function template specialized to deduce the argument
then when the argument is an lvalue reference to a non-constinit static object,
clang fails to match it as valid NTTP and rejects with a substitution error
https://godbolt.org/z/aYEaG4jx3
```c++
template <decltype(auto)v> struct DA {};
template <decltype(auto)v>
constexpr decltype(v) get(DA<v>) { return v; }
int g;
static_assert( &get(DA<(g)>{}) == &g ); // substitution failure
^~~
// note: candidate template ignored: substitution failure:
// non-type template argument is not a constant expression
```
(the parens `(g)` are needed to convert the id-expression to lvalue)
Same with a class specialization https://godbolt.org/z/Pzo9TMrGd
```c++
template <typename> struct Get;
template <decltype(auto)v> struct Get<DA<v>> {};
Get<DA<(g)>> G;
^
// error: implicit instantiation of undefined template 'Get<DA<g>>'
```
GCC and MSVC accept with no error, over many releases.
A workaround is to employ a hidden friend, as then no 'forwarding' is needed, with direct in-class access to the template argument.
It's an intrusive and non-generic workaround though.
https://godbolt.org/z/E1WfTK6Gh
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJydVV2v4jYQ_TXhxQKFBEJ44IGPu6iqtlp1r7bqU2XiSeJtsJHtwHJ_fY8duGSBqldF4Wtsn5k5c2a80-K8-J2-U-EsO_JGCuZof2i4I2YPVEiY3riTWrGTdDXjzLY766Rrg63ksmkNjaJ4E8XL7vNlVI1YJY-ksLtouLU3yAvGOkpWeMYzFmWxoKJx5wNFSc5bp6NkDiPD_oJq3Qgy7MAN35Mj0zngSrCyVUWI4DFaQgqaCRJtQczVxLip2j0p152GBbn4j_4ak5ZxxRpQ0BIzVJIh5c9rhKu0GhZaIW0lHbMOfBRM7zxpUbLuYJGoqgIf1h_ac1fUDLv5ldbfXl-_MB-6ubD9jE8yRl-yrJ072ChdRsknPJUWO924kTYV_r3hzf984dvJ9x_phfss7p6i47azshs_Ubp-ZPoYpS9IyLSFY5sli2araLaJ0lW_nh_BuO4MLNGPg2G9fUdsYhWBq3yzBEQ4ABO8gQzXGsVgWjHv-ie_EnWp3qNhF-b_gqLIeDQWJVkPF9-VVw_Quzy8jxTpbMJGFtbgJhD6VMdXR_evaArI8HTxdQhKO0KBWIGqSuH5eSdKVkobEn71qZ90eYekhp6sG0Bfl_DjO8lTy2Hx9JK1gLur_BUy98JGz5Cyvr-utKCpYGOKSHQtAsQjiAx9IMXwhusXu07w5wLqVzTgVbFdT99Nh_-S65c3PX_9bLbi43L1jCj47Wl0i2qn_0Pb4dz6pj6s_IvWezt7esL-bc_xgzj6xbw0MUovEZ4sMARkVzrZUaVL1ipBpVTUm7ZRMuv5rjqvMD4t8na9DrPk89dv-FEUdHBddZS-uE_WTKO6GETqjC5riFuyP83pJTtp8zc3GsF4maHoPhZ9RolrKQQmZGkkKeGxMMbC4AQ-Yiq1OXEjpAI_syDRICq_MUQhpMGIQ9rDTis-Qhs8eK09iPwS1i_o5FkYw2h801pcISFJ3x0VKTKYur2QXa3bqh59bFq-jP8oX3_NtvWAFuMsy-bzLI-zgVikYp7O-QAd2tAimq7CHI-mm1uUj8p62tMMpDy_KXwr-SvlPd9Ba5rFXcSgrd2NCr3Hn6Y5Xr-GB6O7e-aTtLYlix_TPMuTQb0oJ1kaz0Q5zhPOExrPx0UW4-aK8zKZ57EYNHxHjfVZIaGBXCRxkozjJE-SSRxnoyKfTOfExzHPpmJaZNEkpj2SGXnHnruBWYQYdm1lsdhI6-xtEYXFmCO64oOcWpvFSTbNyfDzIMS7CMH-A9lTpfY">