diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4309,11 +4309,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()) { + auto BaseTemplate = + Base.getType()->getAs(); + if (BaseTemplate && Context.hasSameTemplateName( + BaseTemplate->getTemplateName(), TN)) { + Diag(IdLoc, diag::ext_unqualified_base_class) + << SourceRange(IdLoc, Init->getSourceRange().getEnd()); + BaseType = Base.getType(); + break; + } + } } } diff --git a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp --- a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp +++ b/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;