Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -4308,11 +4308,21 @@ } if (getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus20) { - auto UnqualifiedBase = R.getAsSingle(); - if (UnqualifiedBase) { - Diag(IdLoc, diag::ext_unqualified_base_class) - << SourceRange(IdLoc, Init->getSourceRange().getEnd()); - BaseType = UnqualifiedBase->getInjectedClassNameSpecialization(); + if (auto UnqualifiedBase = R.getAsSingle()) { + auto *TempSpec = cast( + UnqualifiedBase->getInjectedClassNameSpecialization()); + TemplateName TN = TempSpec->getTemplateName(); + for (auto const &Base : ClassDecl->bases()) { + QualType BT = cast(Base.getType())->getNamedType(); + const auto *BaseTemplate = dyn_cast(BT); + if (BaseTemplate && Context.hasSameTemplateName( + BaseTemplate->getTemplateName(), TN)) { + Diag(IdLoc, diag::ext_unqualified_base_class) + << SourceRange(IdLoc, Init->getSourceRange().getEnd()); + BaseType = BT; + break; + } + } } } Index: clang/test/SemaTemplate/ms-unqualified-base-class.cpp =================================================================== --- clang/test/SemaTemplate/ms-unqualified-base-class.cpp +++ clang/test/SemaTemplate/ms-unqualified-base-class.cpp @@ -83,3 +83,37 @@ return I; } + +template class Vec {}; // expected-note {{template is declared here}} + +template class Index : public Vec { + // 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 class Array : public Vec { + // 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; + +template class Wrong : public Vec { + Wrong() : NonExistent() {} // expected-error {{member initializer 'NonExistent' does not name a non-static data member or base class}} +}; + +template class Wrong; + +template class Wrong2 : public Vec { + Wrong2() : Vec() {} // expected-error {{too few template arguments for class template 'Vec'}} +}; + +template class Wrong2; + +template class Wrong3 : public Vec { + Wrong3() : Base() {} // expected-error {{member initializer 'Base' does not name a non-static data member or base class}} +}; + +template class Wrong3;