https://github.com/dyung updated https://github.com/llvm/llvm-project/pull/183824
>From 1eb9bd80061b2fdec8d5dbc435d2e7ee60fb98da Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <[email protected]> Date: Tue, 24 Feb 2026 18:40:57 -0300 Subject: [PATCH] [clang] Backport: fix transformation of substituted constant template parameters of partial specializations This fixes a helper so it implements retrieval of the argument replaced for a template parameter for partial spcializations. This was left out of the original patch, since it's quite hard to actually test. This helper implements the retrieval for variable templates, but only for completeness sake, as no current users rely on this, and I don't think a similar test case is possible to implement with variable templates. This fixes a regression introduced in #161029 which will be backported to llvm-22, so there are no release notes. Backport from #183348 Fixes #181062 Fixes #181410 --- clang/lib/AST/DeclTemplate.cpp | 20 ++++++++++---------- clang/test/SemaTemplate/GH181062.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 clang/test/SemaTemplate/GH181062.cpp diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 2f7ae6d6cac63..ed20c720ce06c 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1668,27 +1668,27 @@ clang::getReplacedTemplateParameter(Decl *D, unsigned Index) { case Decl::Kind::ClassTemplateSpecialization: { const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D); auto P = CTSD->getSpecializedTemplateOrPartial(); - TemplateParameterList *TPL; if (const auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) { - TPL = CTPSD->getTemplateParameters(); - // FIXME: Obtain Args deduced for the partial specialization. - return {TPL->getParam(Index), {}}; + TemplateParameterList *TPL = CTPSD->getTemplateParameters(); + return {TPL->getParam(Index), + CTSD->getTemplateInstantiationArgs()[Index]}; } - TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters(); + TemplateParameterList *TPL = + cast<ClassTemplateDecl *>(P)->getTemplateParameters(); return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]}; } case Decl::Kind::VarTemplateSpecialization: { const auto *VTSD = cast<VarTemplateSpecializationDecl>(D); auto P = VTSD->getSpecializedTemplateOrPartial(); - TemplateParameterList *TPL; if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) { - TPL = VTPSD->getTemplateParameters(); - // FIXME: Obtain Args deduced for the partial specialization. - return {TPL->getParam(Index), {}}; + TemplateParameterList *TPL = VTPSD->getTemplateParameters(); + return {TPL->getParam(Index), + VTSD->getTemplateInstantiationArgs()[Index]}; } - TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters(); + TemplateParameterList *TPL = + cast<VarTemplateDecl *>(P)->getTemplateParameters(); return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]}; } case Decl::Kind::ClassTemplatePartialSpecialization: diff --git a/clang/test/SemaTemplate/GH181062.cpp b/clang/test/SemaTemplate/GH181062.cpp new file mode 100644 index 0000000000000..001c74348346e --- /dev/null +++ b/clang/test/SemaTemplate/GH181062.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s + +namespace invalid_partial_spec { + template <int> struct integer_sequence {}; + template <int> struct array {}; + template <int*> struct MetaValuesHelper; // expected-note {{template is declared here}} + + template <typename TupleName, TupleName kValues> + struct MetaValuesHelper<kValues> { + // expected-error@-1 {{class template partial specialization is not more specialized than the primary template}} + template <int... Is> + static array<undefined<Is>(kValues)...> MetaValuesFunc(integer_sequence<Is...>); + // expected-note@-1 {{candidate template ignored: substitution failure [with Is = <0>]: use of undeclared identifier 'undefined'}} + }; + + int kBaseIndexRegistersUsed; + + constexpr array<0> GenMachineInsnInfos() { + return decltype(MetaValuesHelper<&kBaseIndexRegistersUsed>::MetaValuesFunc(integer_sequence<0>{})){}; + // expected-error@-1 {{no matching function for call to 'MetaValuesFunc'}} + } + + array<0> u = GenMachineInsnInfos(); +} // namspace invalid_partial_spec _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
