[llvm-branch-commits] [clang] 108df06 - [clang] Backport: fix transformation of substituted constant template parameters of partial specializations

Douglas Yung via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Feb 28 01:27:19 PST 2026


Author: Matheus Izvekov
Date: 2026-02-28T09:27:07Z
New Revision: 108df0694cc12fa496f63faa3a8762e7cc1a3b37

URL: https://github.com/llvm/llvm-project/commit/108df0694cc12fa496f63faa3a8762e7cc1a3b37
DIFF: https://github.com/llvm/llvm-project/commit/108df0694cc12fa496f63faa3a8762e7cc1a3b37.diff

LOG: [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

Added: 
    clang/test/SemaTemplate/GH181062.cpp

Modified: 
    clang/lib/AST/DeclTemplate.cpp

Removed: 
    


################################################################################
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 at -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 at -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 at -1 {{no matching function for call to 'MetaValuesFunc'}}
+  }
+
+  array<0> u = GenMachineInsnInfos();
+} // namspace invalid_partial_spec


        


More information about the llvm-branch-commits mailing list