https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/65993:
As reported in GH65810, we don't properly collect ALL of the template parameters in a nested name specifier, and were only doing the 'inner level'. This patch makes sure we collect from all levels. Fixes: #65810 >From 52bcb5537fe67cdb93d50c16de181d87a7bcffc5 Mon Sep 17 00:00:00 2001 From: erichkeane <eke...@nvidia.com> Date: Mon, 11 Sep 2023 11:28:04 -0700 Subject: [PATCH] Fix out of line Concept-comparisons of NestedNameSpecifiers As reported in GH65810, we don't properly collect ALL of the template parameters in a nested name specifier, and were only doing the 'inner level'. This patch makes sure we collect from all levels. Fixes: #65810 --- clang/docs/ReleaseNotes.rst | 3 ++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 18 ++++--- .../SemaTemplate/concepts-out-of-line-def.cpp | 48 +++++++++++++++++++ 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index cc8b2c3808933cb..872c32f59da96ad 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -218,6 +218,9 @@ Bug Fixes in This Version (`#65156 <https://github.com/llvm/llvm-project/issues/65156>`_`) - Clang no longer considers the loss of ``__unaligned`` qualifier from objects as an invalid conversion during method function overload resolution. +- Clang now properly handles out of line template specializations when there is + a non-template inner-class between the function and the class template + (`#65810 <https://github.com/llvm/llvm-project/issues/65810>`_). Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 3b1731edec95237..832837556601663 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -231,14 +231,18 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD, MultiLevelTemplateArgumentList &Result) { if (!isa<ClassTemplateSpecializationDecl>(FTD->getDeclContext())) { NestedNameSpecifier *NNS = FTD->getTemplatedDecl()->getQualifier(); - const Type *Ty; - const TemplateSpecializationType *TSTy; - if (NNS && (Ty = NNS->getAsType()) && - (TSTy = Ty->getAs<TemplateSpecializationType>())) - Result.addOuterTemplateArguments(const_cast<FunctionTemplateDecl *>(FTD), - TSTy->template_arguments(), - /*Final=*/false); + + while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) { + + if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) + Result.addOuterTemplateArguments( + const_cast<FunctionTemplateDecl *>(FTD), TSTy->template_arguments(), + /*Final=*/false); + + NNS = NNS->getPrefix(); + } } + return Response::ChangeDecl(FTD->getLexicalDeclContext()); } diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index 4688c28b489307f..f067c02ca48f584 100644 --- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -418,3 +418,51 @@ template<typename T> concept A = true; template<typename T> struct X { A<T> auto f(); }; template<typename T> A<T> auto X<T>::f() {} } + +namespace GH65810 { +template<typename Param> +concept TrivialConcept = +requires(Param param) { + (void)param; +}; + +template <typename T> +struct Base { + class InnerClass; +}; + +template <typename T> +class Base<T>::InnerClass { + template <typename Param> + requires TrivialConcept<Param> + int func(Param param) const; +}; + +template <typename T> +template <typename Param> +requires TrivialConcept<Param> +int Base<T>::InnerClass::func(Param param) const { + return 0; +} + +template<typename T> +struct Outermost { + struct Middle { + template<typename U> + struct Innermost { + template <typename Param> + requires TrivialConcept<Param> + int func(Param param) const; + }; + }; +}; + +template <typename T> +template <typename U> +template <typename Param> +requires TrivialConcept<Param> +int Outermost<T>::Middle::Innermost<U>::func(Param param) const { + return 0; +} + +} // namespace GH65810 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits