Description
Bugzilla Link | 50723 |
Version | unspecified |
OS | All |
CC | @CaseyCarter,@DougGregor,@zygoloid |
Extended Description
Clang incorrectly accepts this code, despite S<int*, int*>
having no member named foo
:
template<typename T, typename U> struct S {};
template<typename T> struct S<T, T> {};
template<typename T, typename U> struct S<T*, U*> {};
template<typename ... Ts> using V = void;
template<typename T, typename U = void> struct X {}; // #​1
template<typename T> struct X<T, V<typename S<T, T>::type>>; // #​2
X<int*> xpi;
S<int*, int*>::foo x = "hello";
What's happening here is that we try to instantiate S<int*, int*>
as part of considering #2
, but fail because the partial specialization selection for S
results in an ambiguity. We mark S<int*, int*>
as invalid and produce a diagnostic. However, because this all happens in the immediate context of the partial specialization selection for #2
, we swallow the diagnostic and instead select #1
.
Then when we try to form S<int*, int*>::foo
, because S<int*, int*>
is marked as invalid we form an invalid type and don't produce any diagnostic (incorrectly thinking we already produced one).
Probably the right approach here is to treat ambiguity during partial specialization selection as not being part of the immediate context. That's what GCC and EDG do. (MSVC, like Clang, treats this ambiguity as being in the immediate context, and has very similar kinds of brokenness for examples like this one.)