<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/102502>102502</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[Clang][C++23] `<` not parsed as the start of a template list in type-only contexts
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
MitalAshok
</td>
</tr>
</table>
<pre>
https://eel.is/c++draft/temp.names#3
> A `<` is interpreted as the delimiter of a *template-argument-list* if it follows a name [...] that is [...] in a type-only context other than a *nested-name-specifier*.
This wording was added by [P1787R6](https://wg21.link/P1787R6) for C++23
https://godbolt.org/z/GanbhKTh1
```c++
template<typename T>
struct X : T::type<void> {};
template<typename T, typename = typename T::type<void>>
int Y = sizeof(typename T::type<void>);
// CWG2806
template<typename T>
concept C = requires {
typename T::type<void>;
};
// CWG2903
template<typename T>
struct Z : T::type<void>::type {};
```
Last two are valid after https://cplusplus.github.io/CWG/issues/2806.html and https://cplusplus.github.io/CWG/issues/2903.html
```
<source>:2:15: error: use 'template' keyword to treat 'type' as a dependent template name
2 | struct X : T::type<void> {};
| ^
| template
<source>:4:45: error: use 'template' keyword to treat 'type' as a dependent template name
4 | template<typename T, typename = typename T::type<void>>
| ^
| template
<source>:5:28: error: use 'template' keyword to treat 'type' as a dependent template name
5 | int Y = sizeof(typename T::type<void>);
| ^
| template
<source>:10:15: error: use 'template' keyword to treat 'type' as a dependent template name
10 | typename T::type<void>;
| ^
| template
<source>:15:15: error: use 'template' keyword to treat 'type' as a dependent template name
15 | struct Z : T::type<void>::type {};
| ^
| template
```
This compiles with `-fms-extensions`.
MSVC only compiles this with `/permissive` (not `/permissive-`):
```c++
template<typename T, typename = typename T::type<void>>
int Y = sizeof(typename T::type<void>);
```
GCC compiles it all.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEVktzo0YQ_jWtS5coaISQDjpIaPEh2apU4somuY2gEROPGDIzWOv99alB77X8WGfjpYyNZ6Yf39d08wlr5bphnkGygGQ5EJ2rtZl9lE6oua313WCly4dZ7VxrIZ4D5UA5swqkBcoLoAXQojSickC5400bNGLDFiiOIVxCON__jj_gHGEcQpzBOERpUTaOTWvYcYnCoqsZS1ZyIx0b1BUKBJp7j0o4Hgqz7jbcuKGS1gHNUVYoHVZaKb21KNCHRUgWQRBAskRXC-ejnFZkgwLdQ8tD3agHLHTj-LND7Wo2_nizi9iwdVwOvbuhbbmQlWQDNA_O4dzW0uJWm1I2a9wKi6IsucTVg4_3S5RO0l_HkCyBJpfEbdcUBUo2d0D54RhNsdIGsx2VdEHbpfValyutXKDNGij_ApTfiGZV_3RbRxdcj8Pdz746u9UDkxBnnoSerluIP-x2rTNd4fAPhHjul-cQz_0xiLN7LUtfPkgXkC4hXpzHuu6VMjz-B_ESzwM-9nxMQjYO_-wNrPzCugKavGBJ06_y2RGF2acbmoTj1yAvdFNw6zDrAxv-p5OGbY-238cXsz8k8Iics2SmYfwNZfjr6TKc1h4V5FD28xR-Ftah22oUhvFeKFmiqHyDXb5ZRas66-9gLV3drQKpgfLs0w1QLq3tfEPnntGgdhuFoinf5GAaxr2Dq2_rYVBkVnem4B1WgngeJZ4NNkYb_9BZRqD0SCSleMcPvhnRaXSGhev3PW2U-tEisOSWm5Ibhwezfl4cKoxICGmG394F2F_e9vKCZF_RK3vHFK4iHvn7HRCP-sy-a_-eyDjBf4Kf56_nGfLk0OT_Zyjp8_5PQ-lV8K-Q9TwBUfg-XRGF-9RfOQFfboYnDrwAN3knuMn5EHjTDP4e4K-N8V5vFHrTSsUWt9LVXksNq40d8mfHjZW6sTAOL0TKx99-z3CvdfaWrtcte3OgvGWzkdbKe_aiDGjSaPdoa9gvTD3qN6qMH6IHrvF4k2UnMqRDoVQwKGdxOY2nYsCzKKU4isdJNBnUsypOyxFFIU9C5pGYjjkapysSaRUlPKV4IGcU0iichJMoDaNkHETxNKp4JMZVEpVVksAo5I2QKlDqfuNl26D_Fs6ikJKQBkqsWNleeRMVSjRrIPIi3My8wXDVrS2MQq947cmFk071cj3rLZKlfzyKx2R5prJ9NVth7ElhWyeM26nr43vn_Xt1_Egb20Fn1FfSf_95L_QGKPc57f8MW6P_5sKdf-_3MO9n9G8AAAD__6uYj-8">