https://gcc.gnu.org/g:969f4493630adac2ce35ad8a3e105323dc4c0016

commit r16-8462-g969f4493630adac2ce35ad8a3e105323dc4c0016
Author: Jakub Jelinek <[email protected]>
Date:   Sat Apr 4 11:18:20 2026 +0200

    c++: Partially implement mangling for C++26 pack indexing [PR124487]
    
    I still haven't figured out how to correctly mangle the case
    in pack-indexing9.C where write_type is called with PACK_INDEX_TYPE
    where PACK_INDEX_PACK is TREE_VEC of types, i.e. already expanded pack,
    but given that right now we sorry on mangling of all PACK_INDEX_TYPE
    or PACK_INDEX_EXPR trees, I think the following patch is an incremental
    progress in the right direction and just mangles what is clearly specified
    in the proposal.
    
    This patch relies on the PR124198 patch I've just posted, because the
    casts to size_t change mangling of pack...[1] from having i1 in it
    to m1 (on x86_64, j1 on ia32, ...).
    
    2026-04-04  Jakub Jelinek  <[email protected]>
    
            PR c++/124487
            * mangle.cc (write_type) <case PACK_INDEX_TYPE>: Handle pack index
            mangling unless (for now) PACK_INDEX_PACK is a TREE_VEC.
            (write_expression): Handle PACK_INDEX_EXPR.
    
            * g++.dg/cpp26/pack-indexing7.C: Don't xfail dg-bogus.
            * g++.dg/cpp26/pack-indexing22.C: New test.

Diff:
---
 gcc/cp/mangle.cc                             | 30 +++++++++++++++--
 gcc/testsuite/g++.dg/cpp26/pack-indexing22.C | 50 ++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp26/pack-indexing7.C  |  2 +-
 3 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 17ffacd5952d..9eb09dcede75 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -2744,9 +2744,18 @@ write_type (tree type)
              break;
 
            case PACK_INDEX_TYPE:
-             /* TODO Mangle pack indexing
-                <https://github.com/itanium-cxx-abi/cxx-abi/issues/175>.  */
-             sorry ("mangling type pack index");
+             /* https://github.com/itanium-cxx-abi/cxx-abi/issues/175.  */
+             if (TREE_CODE (PACK_INDEX_PACK (type)) == TREE_VEC)
+               {
+                 /* TODO: How should this be mangled when the pack is already
+                    expanded?  */
+                 sorry ("mangling type pack index");
+                 break;
+               }
+             write_string ("Dy");
+             /* Dy rather than DyDp.  */
+             write_type (PACK_EXPANSION_PATTERN (PACK_INDEX_PACK (type)));
+             write_expression (PACK_INDEX_INDEX (type));
              break;
 
            case LANG_TYPE:
@@ -3602,6 +3611,21 @@ write_expression (tree expr)
       else
        goto normal_expr;
     }
+  else if (code == PACK_INDEX_EXPR)
+    {
+      /* https://github.com/itanium-cxx-abi/cxx-abi/issues/175.  */
+      if (TREE_CODE (PACK_INDEX_PACK (expr)) == TREE_VEC)
+       /* TODO: How should this be mangled when the pack is already
+          expanded?  */
+       sorry ("mangling type pack index");
+      else
+       {
+         write_string ("sy");
+         /* sy rather than sysp.  */
+         write_expression (PACK_EXPANSION_PATTERN (PACK_INDEX_PACK (expr)));
+         write_expression (PACK_INDEX_INDEX (expr));
+       }
+    }
   else if (TREE_CODE (expr) == ALIGNOF_EXPR)
     {
       if (!ALIGNOF_EXPR_STD_P (expr))
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing22.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing22.C
new file mode 100644
index 000000000000..6e6c32082a12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing22.C
@@ -0,0 +1,50 @@
+// PR c++/124487
+// { dg-do compile { target c++20 } }
+// { dg-options "" }
+
+template <int I, typename... T>
+struct A {
+  using B = T...[I];                           // { dg-warning "pack indexing 
only available with" "" { target c++23_down } }
+  A () requires (requires { B {}; }) {}
+};
+
+template <int I, auto... J>
+struct C {
+  using B = decltype (J...[I]);                        // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+  C () requires (requires { B {}; }) {}
+};
+
+template <int I, auto... J>
+decltype (J...[I]) foo () { return 0; }                // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+
+template <int I, typename... T>
+T...[I] bar () { return 0; }                   // { dg-warning "pack indexing 
only available with" "" { target c++23_down } }
+
+template <int I, typename... T>
+using D = T...[I];                             // { dg-warning "pack indexing 
only available with" "" { target c++23_down } }
+
+template <int I, typename... T>
+void baz (D <I, int, T...>) {}
+
+template <auto... J>
+decltype (J...[1]) corge () { return 0; }      // { dg-warning "pack indexing 
only available with" "" { target c++23_down } }
+
+void
+qux ()
+{
+  // { dg-final { scan-assembler "_ZN1AILi3EJilsiEEC1EvQrqXtlDyT0_T_EE" } }
+  A <3, int, long, short, int> a;
+  // { dg-final { scan-assembler 
"_ZN1CILi2EJLi0ELx0ELj0ELl0EEEC1EvQrqXtlDtsyT0_T_EEE" } }
+  C <2, 0, 0LL, 0U, 0L> c;
+  // { dg-final { scan-assembler "_Z3fooILi0ETpTnDaJLi1EEEDtsyT0_T_Ev" } }
+  foo <0, 1> ();
+  // { dg-final { scan-assembler 
"_Z3fooILi2ETpTnDaJLj1ELl2ELx3ELd4010000000000000EEEDtsyT0_T_Ev" } }
+  foo <2, 1U, 2L, 3LL, 4.0> ();
+  // { dg-final { scan-assembler "_Z3barILi0EJiEEDyT0_T_v" } }
+  bar <0, int> ();
+  // { dg-final { scan-assembler "_Z3barILi3EJjlxdEEDyT0_T_v" } }
+  bar <3, unsigned, long, long long, double> ();
+//  baz <0, int> ();
+  // { dg-final { scan-assembler 
"_Z5corgeITpTnDaJLi1ELx2ELj3ELl4ELi5EEEDtsyT_L\[jmy]1EEv" } }
+  corge <1, 2LL, 3U, 4L, 5> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing7.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing7.C
index de50f7758e30..0447128e5fe5 100644
--- a/gcc/testsuite/g++.dg/cpp26/pack-indexing7.C
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing7.C
@@ -4,7 +4,7 @@
 
 template <int I, auto...Ts>
 decltype(Ts...[I])
-foo ()                       // { dg-bogus "sorry, unimplemented: mangling" "" 
{ xfail *-*-* } }
+foo ()                       // { dg-bogus "sorry, unimplemented: mangling" }
 {
   return Ts...[I];
 }

Reply via email to