Open zygoloid opened 4 months ago
@llvm/issue-subscribers-c-20
Author: Richard Smith (zygoloid)
@llvm/issue-subscribers-clang-frontend
Author: Richard Smith (zygoloid)
Another case where Clang misses some of the P1787 changes for the handling of template
:
template<template<typename> typename> struct X {};
template<typename T> void f() {
X<T::R>(); // #1
X<typename T::R>(); // #2
X<T::template R>(); // #3
X<typename T::template R>(); // #4
}
struct D { template<typename> class R {}; };
void g() { f<D>(); }
Under P1787:
#1
is valid, and is interpreted as naming the template D::R
in the instantiation of f
. (Prior to P1787 it was not valid. Clang incorrectly rejects.)
#2
is ill-formed; typename T::R
unambiguously names a type, not a template. (Clang correctly rejects.)
#3
is valid but deprecated by P1787. (Prior to P1787, it was the only way to pass the member template as a template argument; Clang accepts without a deprecation warning.)
#4
is presumably ill-formed; T::R
cannot be both a template and a type. (Clang rejects.)
Unlike the previous case (which should be applied only in the language modes with implicit typename
/ P0634), this one should presumably be applied retroactively across all C++ standards.
CC @Endilll
One more place is in typename T::template X<0>
, as made optional by CWG1710, which is a DR presumably against all versions.
Testcase:
Under P1787 (DR against C++20), per [temp.names]/3, the
template
keyword is not required beforeX
ing
andh
, following the same rules that P0634 established for type-only contexts. But Clang (and GCC) seems to not implement this, and still requirestemplate
ing
andh
.