Clang fails to diagnose static_cast<> issue in member function of class template

My commit earlier broke the VC++ build, and I’ve reduced the code to the following (at the bottom).

I’m not sure if this is something Clang should diagnose, something VC++ shouldn’t diagnose, or if both behaviors are considered correct.

Clang only emits a diagnostic if there is a function body that declares a value of Derived<Other> - it doesn’t emit a diagnostic for member variables of type Derived<Other>. Should it eagerly diagnose this?

Another very odd thing I noticed is that even with a function body with a variable of type Derived<Other>, Clang fails to emit a diagnostic if Derived::Foo is non-virtual (uncomment Bar() below and comment-out “virtual” before Foo()).


class Base {
  class Inner {};

template<class T> class Derived : public Base {
  // Clang only emits a diagnostic if this is virtual.
  // error: static_cast from 'Base::Inner *' to 'Other *' is not allowed
  // T *TN = static_cast<T *>(N);
  void Foo(Inner *N) {
    T *TN = static_cast<T *>(N);

class Other;

class Container {
  Derived<Other> Data;
  // Clang only emits a diagnostic if there is a function body using
  // Dervied<Other>, not if there is simply a member declaration using
  // Derived<Other>.
  // void Bar() { Derived<Other> D; }

As far as I understand, [temp.inst]/11 applies here:

[...] It is unspecified whether or not an implementation implicitly
instantiates a virtual member function of a class template if the
virtual member function would not otherwise be instantiated. [...]