https://github.com/mizvekov created 
https://github.com/llvm/llvm-project/pull/183348

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.

Fixes #181062
Fixes #181410

>From 7decfaf850ba41ab976128e9f1c6345d8ee372f7 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <[email protected]>
Date: Tue, 24 Feb 2026 18:40:57 -0300
Subject: [PATCH] [clang] 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.

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 e76e46499038c..5a8e1ed445f3a 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -1662,27 +1662,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

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to