Author: Erich Keane Date: 2023-09-12T06:40:32-07:00 New Revision: bfddbdaff06ca619a2c1889b358c44ff3546c76c
URL: https://github.com/llvm/llvm-project/commit/bfddbdaff06ca619a2c1889b358c44ff3546c76c DIFF: https://github.com/llvm/llvm-project/commit/bfddbdaff06ca619a2c1889b358c44ff3546c76c.diff LOG: Fix out of line Concept-comparisons of NestedNameSpecifiers (#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 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaTemplate/concepts-out-of-line-def.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c7b4432380120cb..768b322ca5e721d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -275,6 +275,10 @@ Bug Fixes to C++ Support (`#65067 <https://github.com/llvm/llvm-project/issues/65067>`_ and `#63675 <https://github.com/llvm/llvm-project/issues/63675>`_) +- 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 AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 3b1731edec95237..c723e47ffca8ecd 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -230,15 +230,25 @@ Response HandleFunction(const FunctionDecl *Function, Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD, MultiLevelTemplateArgumentList &Result) { if (!isa<ClassTemplateSpecializationDecl>(FTD->getDeclContext())) { + Result.addOuterTemplateArguments( + const_cast<FunctionTemplateDecl *>(FTD), + const_cast<FunctionTemplateDecl *>(FTD)->getInjectedTemplateArgs(), + /*Final=*/false); + 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 (NNS->isInstantiationDependent()) { + 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