Flag for better diagnosing errors in member templates

I would appreciate a clang flag that leads to better diagnosis in member templates. Consider

     template<typename T>
     struct A {
       template<typename U>
       void f(U u) {
         T t;
         // ...
       }
     };

     struct B;
     template struct A<B>;

A<B>::f's definition is ill-formed without a diagnostic being required and Clang does not diagnose it. But Clang aims for catching as many bugs as possible in user programs, and finding this bug appears to be possible with the current clang abilities.

What do you think?

I'm pretty sure this is NOT an issue until A<B>::f is instantiated. It's possible a specialization of A<B>::f could be introduced that did not declare a B, or that B's definition could be completed before A<B>::f is actually used. That said, I understand your point about "catching as many bugs as possible", so maybe we could add this as an optional warning?

I'm basing this on my intuition of how C++ behaves, though, not on the actual standard.

Jordan

I think we may be talking about two different "instantiations" here. There are two entities that can be instantiated with regard to that "f" function template: The still-templated member definition of the class A<B> when T is provided, and the non-template function when U is provided.

What the user defined is A<T>::f<U>. When he explicitly instantiates A for T = B, then "An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members (not including members inherited from base classes) that has not been previously explicitly specialized in the translation unit containing the explicit instantiation, except as described below.".

Hence when A<B> is instantiated, that will also instantiate A<B>::f, which leaves us with

     struct A<B> {
       template<typename U>
       void f(U u) {
         B t;
       }
     };

This template definition is ill-formed, because B was still incomplete at that point.

Ah, right. In my mind that was not ill-formed, because A::f hasn't been instantiated yet. But of course the reference to "B" is already bound, as well as the implicit reference to B's constructor. So yes, this would be something we could diagnose in theory.

Jordan