[llvm-branch-commits] [clang] release/23.x: Backport "[Clang] Fix C++26 fold expression normalization of PackIndexingExpr" (PR #220156)

Younan Zhang via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Aug 31 23:00:55 PDT 2026


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

It turns out that PackIndexingExpr doesn't create any PackExpansionTypes for unexpanded packs and thus we don't have to remove the packs during the normalization.

This backports https://github.com/llvm/llvm-project/pull/218577


>From ad8761de853622362a71aec6a3573b7c403fcc0b Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 24 Aug 2026 18:39:54 +0800
Subject: [PATCH] release/23.x: Backport '[Clang] Fix C++26 fold expression
 normalization of PackIndexingExpr'

It turns out that PackIndexingExpr doesn't create any PackExpansionTypes
for unexpanded packs and thus we don't have to remove the packs during the normalization.
---
 clang/lib/Sema/SemaConcept.cpp          |  6 +++++
 clang/test/SemaCXX/cxx2c-fold-exprs.cpp | 30 +++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 476910a9db528..da0b9700504b9 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -267,6 +267,12 @@ class AdjustConstraints : public TreeTransform<AdjustConstraints> {
     return Result;
   }
 
+  QualType TransformPackIndexingType(TypeLocBuilder &TLB,
+                                     PackIndexingTypeLoc TL) {
+    llvm::SaveAndRestore _1(RemoveNonPackExpansionPacks, false);
+    return inherited::TransformPackIndexingType(TLB, TL);
+  }
+
   bool AlreadyTransformed(QualType T) {
     if (T.isNull())
       return true;
diff --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
index 0312022912dca..87a3b311857f4 100644
--- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
+++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
@@ -598,3 +598,33 @@ 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>(); }
+
+}
+
+namespace GH218548 {
+
+template <class T>
+concept same_as_impl = sizeof(T) == 2;
+template <typename... P>
+void f() requires(same_as_impl<P...[sizeof(P)]> && ...) // #GH218548_f
+{}
+void g() {
+  f<char, short, short>();
+
+  f<char, int, short>();
+  // expected-error at -1 {{no matching function}}
+  // expected-note@#GH218548_f {{constraints not satisfied}}
+  // expected-note@#GH218548_f {{invalid index}}
+}
+
+}



More information about the llvm-branch-commits mailing list