[clang] [Clang] Clear outer SubstIndex when normalizing PackIndexingType (PR #218257)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 23 09:05:15 PDT 2026


https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/218257

When we instantiate a fold-expression concept we expand the template arguments outside of the TreeTransform. However a PackIndexingType should gain its own index from the index expression, not the outer SubstIndex.

The bug occurs because we don't support rewrite of PackIndexingType, which the default transform unexpectedly expands the pattern in the normalization so that the instantiation picks up the outer SubstIndex that is set up for a fold expression.

This is identical to the fix to the pattern transform, and in fact we're unnecessarily transforming the pattern of PackIndexingType repeatedly.

This is a regression since 161671, so no release note for backporting.

Fixes #218035

>From e736146b4a19305ae4914323b7f6db236a2e04b0 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sun, 23 Aug 2026 23:51:51 +0800
Subject: [PATCH] [Clang] Clear outer SubstIndex when normalizing
 PackIndexingType

When we instantiate a fold-expression concept we expand the template
arguments outside of the TreeTransform. However a PackIndexingType
should gain its own index from the index expression, not the outer SubstIndex.

The bug occurs because we don't support rewrite of PackIndexingType, which
the default transform unexpectedly expands the pattern in the normalization
so that the instantiation picks up the outer SubstIndex that is set up for
a fold expression.

This is identical to the fix to the pattern transform, and in fact we're
unnecessary transforming the pattern of PackIndexingType repeatedly.

This is a regression since 161671, so no release note for backporting.
---
 clang/lib/Sema/TreeTransform.h          |  4 ++++
 clang/test/SemaCXX/cxx2c-fold-exprs.cpp | 12 ++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 4799f72dd6177..b0c836325a971 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7124,6 +7124,10 @@ TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
 
   for (QualType T : Types) {
     if (!T->containsUnexpandedParameterPack()) {
+      // A pack indexing type can appear in a larger pack expansion,
+      // e.g. `Pack...[pack_of_indexes]...`
+      // so we need to temporarily disable substitution of pack elements
+      Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
       QualType Transformed = getDerived().TransformType(T);
       if (Transformed.isNull())
         return QualType();
diff --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
index bd9dff73cb640..79d57a6f94d58 100644
--- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
+++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
@@ -629,3 +629,15 @@ static_assert(MutabilityAlias<Constant::alias>);
 static_assert(MutabilityAlias<Mutable::alias>);
 
 }
+
+namespace GH218035 {
+
+template <class T, class UnusedParam>
+concept same_as_impl = sizeof(T) == 8;
+template <typename... P>
+void f()
+  requires(same_as_impl<P...[0], P> && ...)
+{}
+void g() { f<long long, float>(); }
+
+}



More information about the cfe-commits mailing list