This revision was automatically updated to reflect the committed changes. Closed by commit rGba1c396e09a6: MSVC compatibility mode: fix error on unqualified templated base class… (authored by frederic-tingaud-sonarsource, committed by steakhal).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D130709/new/ https://reviews.llvm.org/D130709 Files: clang/lib/Sema/SemaDeclCXX.cpp clang/test/SemaTemplate/ms-unqualified-base-class.cpp 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 <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>; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -4309,11 +4309,21 @@ } if (getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus20) { - auto UnqualifiedBase = R.getAsSingle<ClassTemplateDecl>(); - if (UnqualifiedBase) { - Diag(IdLoc, diag::ext_unqualified_base_class) - << SourceRange(IdLoc, Init->getSourceRange().getEnd()); - BaseType = UnqualifiedBase->getInjectedClassNameSpecialization(); + if (auto UnqualifiedBase = R.getAsSingle<ClassTemplateDecl>()) { + auto *TempSpec = cast<TemplateSpecializationType>( + UnqualifiedBase->getInjectedClassNameSpecialization()); + TemplateName TN = TempSpec->getTemplateName(); + for (auto const &Base : ClassDecl->bases()) { + auto BaseTemplate = + Base.getType()->getAs<TemplateSpecializationType>(); + if (BaseTemplate && Context.hasSameTemplateName( + BaseTemplate->getTemplateName(), TN)) { + Diag(IdLoc, diag::ext_unqualified_base_class) + << SourceRange(IdLoc, Init->getSourceRange().getEnd()); + BaseType = Base.getType(); + 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 <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>; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -4309,11 +4309,21 @@ } if (getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus20) { - auto UnqualifiedBase = R.getAsSingle<ClassTemplateDecl>(); - if (UnqualifiedBase) { - Diag(IdLoc, diag::ext_unqualified_base_class) - << SourceRange(IdLoc, Init->getSourceRange().getEnd()); - BaseType = UnqualifiedBase->getInjectedClassNameSpecialization(); + if (auto UnqualifiedBase = R.getAsSingle<ClassTemplateDecl>()) { + auto *TempSpec = cast<TemplateSpecializationType>( + UnqualifiedBase->getInjectedClassNameSpecialization()); + TemplateName TN = TempSpec->getTemplateName(); + for (auto const &Base : ClassDecl->bases()) { + auto BaseTemplate = + Base.getType()->getAs<TemplateSpecializationType>(); + if (BaseTemplate && Context.hasSameTemplateName( + BaseTemplate->getTemplateName(), TN)) { + Diag(IdLoc, diag::ext_unqualified_base_class) + << SourceRange(IdLoc, Init->getSourceRange().getEnd()); + BaseType = Base.getType(); + break; + } + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits