1 // RUN: %clang_cc1 -std=c++17 -fms-compatibility -fsyntax-only -verify=before,expected %s 2 // RUN: %clang_cc1 -std=c++17 -fms-compatibility -fdelayed-template-parsing -fsyntax-only -verify=before,expected %s 3 // RUN: %clang_cc1 -std=c++20 -fms-compatibility -fsyntax-only -verify=after,expected %s 4 // RUN: %clang_cc1 -std=c++20 -fms-compatibility -fdelayed-template-parsing -fsyntax-only -verify=after,expected %s 5 6 template <class T> 7 class Base { 8 }; 9 10 template <class T> 11 class Based {}; // Trying to trick the typo detection 12 13 template <class T> 14 class Derived : public Base<T> { 15 public: 16 // after-error@+1 {{member initializer 'Base' does not name a non-static data member or base class}} 17 Derived() : Base() {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} 18 private: 19 int Baze; // Trying to trick the typo detection 20 }; 21 22 template <class T> struct AggregateBase { 23 T i; 24 }; 25 26 template <class T> 27 struct AggregateDerived : public AggregateBase<T> { 28 int i; 29 30 // after-error@+1 {{member initializer 'AggregateBase' does not name a non-static data member or base class}} 31 AggregateDerived(T j) : AggregateBase{4}, i{j} {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} 32 int f() { 33 return i + AggregateBase::i; // expected-warning {{use of undeclared identifier 'AggregateBase'; unqualified lookup into dependent bases of class template 'AggregateDerived' is a Microsoft extension}} 34 } 35 }; 36 37 template <class T, typename U> struct MultiTypesBase { 38 }; 39 40 template <class T, class U> 41 struct MultiTypesDerived : public MultiTypesBase<T, U> { 42 // after-error@+1 {{member initializer 'MultiTypesBase' does not name a non-static data member or base class}} 43 MultiTypesDerived() : MultiTypesBase{} {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} 44 }; 45 46 template <int I> struct IntegerBase { 47 }; 48 49 template <int I> 50 struct IntegerDerived : public IntegerBase<I> { 51 // after-error@+1 {{member initializer 'IntegerBase' does not name a non-static data member or base class}} 52 IntegerDerived() : IntegerBase{} {} // before-warning {{unqualified base initializer of class templates is a Microsoft extension}} 53 }; 54 55 template <class T> struct ConformingBase { 56 T i; 57 }; 58 59 template <class T> 60 struct ConformingDerived : public ConformingBase<T> { 61 int i; 62 63 ConformingDerived(T j) : ConformingBase<T>{4}, i{j} {} 64 int f() { 65 return i + ConformingBase<T>::i; 66 } 67 }; 68 69 int main() { 70 int I; 71 Derived<int> t; 72 73 AggregateDerived<int> AD{2}; 74 AD.AggregateBase::i = 3; 75 I = AD.f(); 76 77 MultiTypesDerived<int, double> MTD; 78 79 IntegerDerived<4> ID; 80 81 ConformingDerived<int> CD{2}; 82 I = CD.f(); 83 84 return I; 85 } 86