| // RUN: %clang_cc1 -std=c++17 -fms-compatibility -fsyntax-only -verify=before,expected %s | 
 | // RUN: %clang_cc1 -std=c++17 -fms-compatibility -fdelayed-template-parsing -fsyntax-only -verify=before,expected %s | 
 | // RUN: %clang_cc1 -std=c++20 -fms-compatibility -fsyntax-only -verify=after,expected %s | 
 | // RUN: %clang_cc1 -std=c++20 -fms-compatibility -fdelayed-template-parsing -fsyntax-only -verify=after,expected %s | 
 |  | 
 | template <class T> | 
 | class Base { | 
 | }; | 
 |  | 
 | template <class T> | 
 | class Based {}; // Trying to trick the typo detection | 
 |  | 
 | template <class T> | 
 | class Derived : public Base<T> { | 
 | public: | 
 |   // after-error@+1 {{member initializer 'Base' does not name a non-static data member or base class}} | 
 |   Derived() : Base() {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} | 
 | private: | 
 |   int Baze; // Trying to trick the typo detection | 
 | }; | 
 |  | 
 | template <class T> struct AggregateBase { | 
 |   T i; | 
 | }; | 
 |  | 
 | template <class T> | 
 | struct AggregateDerived : public AggregateBase<T> { | 
 |   int i; | 
 |  | 
 |   // after-error@+1 {{member initializer 'AggregateBase' does not name a non-static data member or base class}} | 
 |   AggregateDerived(T j) : AggregateBase{4}, i{j} {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} | 
 |   int f() { | 
 |     return i + AggregateBase::i; // expected-warning {{use of undeclared identifier 'AggregateBase'; unqualified lookup into dependent bases of class template 'AggregateDerived' is a Microsoft extension}} | 
 |   } | 
 | }; | 
 |  | 
 | template <class T, typename U> struct MultiTypesBase { | 
 | }; | 
 |  | 
 | template <class T, class U> | 
 | struct MultiTypesDerived : public MultiTypesBase<T, U> { | 
 |   // after-error@+1 {{member initializer 'MultiTypesBase' does not name a non-static data member or base class}} | 
 |   MultiTypesDerived() : MultiTypesBase{} {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} | 
 | }; | 
 |  | 
 | template <int I> struct IntegerBase { | 
 | }; | 
 |  | 
 | template <int I> | 
 | struct IntegerDerived : public IntegerBase<I> { | 
 |   // after-error@+1 {{member initializer 'IntegerBase' does not name a non-static data member or base class}} | 
 |   IntegerDerived() : IntegerBase{} {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} | 
 | }; | 
 |  | 
 | template <class T> struct ConformingBase { | 
 |   T i; | 
 | }; | 
 |  | 
 | template <class T> | 
 | struct ConformingDerived : public ConformingBase<T> { | 
 |   int i; | 
 |  | 
 |   ConformingDerived(T j) : ConformingBase<T>{4}, i{j} {} | 
 |   int f() { | 
 |     return i + ConformingBase<T>::i; | 
 |   } | 
 | }; | 
 |  | 
 | int main() { | 
 |   int I; | 
 |   Derived<int> t; | 
 |  | 
 |   AggregateDerived<int> AD{2}; | 
 |   AD.AggregateBase::i = 3; | 
 |   I = AD.f(); | 
 |  | 
 |   MultiTypesDerived<int, double> MTD; | 
 |  | 
 |   IntegerDerived<4> ID; | 
 |  | 
 |   ConformingDerived<int> CD{2}; | 
 |   I = CD.f(); | 
 |  | 
 |   return I; | 
 | } | 
 |  | 
 | template <typename Type, int TSize> class Vec {}; // expected-note {{template is declared here}} | 
 |  | 
 | template <int TDim> class Index : public Vec<int, TDim> { | 
 |   // after-error@+1 {{member initializer 'Vec' does not name a non-static data member or base class}} | 
 |   Index() : Vec() {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} | 
 | }; | 
 |  | 
 | template class Index<0>; | 
 |  | 
 | template <typename T> class Array : public Vec<T, 4> { | 
 |   // after-error@+1 {{member initializer 'Vec' does not name a non-static data member or base class}} | 
 |   Array() : Vec() {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} | 
 | }; | 
 |  | 
 | template class Array<double>; | 
 |  | 
 | template <typename T> class Wrong : public Vec<T, 4> { | 
 |   Wrong() : NonExistent() {} // expected-error {{member initializer 'NonExistent' does not name a non-static data member or base class}} | 
 | }; | 
 |  | 
 | template class Wrong<double>; | 
 |  | 
 | template <typename T> class Wrong2 : public Vec<T, 4> { | 
 |   Wrong2() : Vec<T>() {} // expected-error {{too few template arguments for class template 'Vec'}} | 
 | }; | 
 |  | 
 | template class Wrong2<double>; | 
 |  | 
 | template <typename T> class Wrong3 : public Vec<T, 4> { | 
 |   Wrong3() : Base() {} // expected-error {{member initializer 'Base' does not name a non-static data member or base class}} | 
 | }; | 
 |  | 
 | template class Wrong3<double>; |