https://gcc.gnu.org/g:1933adbc5446e5ae0282585498ac5f9f8e6c0bdc

commit r16-8501-g1933adbc5446e5ae0282585498ac5f9f8e6c0bdc
Author: Jakub Jelinek <[email protected]>
Date:   Tue Apr 7 18:00:24 2026 +0200

    c++: Implement mangling for partially instantiated C++26 pack indexing 
[PR124487]
    
    On Fri, Apr 03, 2026 at 05:56:08PM -0400, Jason Merrill wrote:
    > Regarding the TODO, the related case I was thinking about was
    >
    > >   ::= sZ <template-param>     # sizeof...(T), size of a template 
parameter pack
    > >   ::= sP <template-arg>* E    # sizeof...(T), size of a captured 
template parameter pack from an alias template
    >
    > ...but rather than follow the precedent of a different two-letter
    > abbreviation, I might use J...E to express the expanded pack, as in
    > <template-arg>.  I've now suggested that on the ABI issue, as well.
    
    Here is a patch which implements it.
    
    2026-04-07  Jakub Jelinek  <[email protected]>
    
            PR c++/124487
            * mangle.cc (write_type) <case PACK_INDEX_TYPE>: Handle even
            the case of partially substituted pack.
            (write_expression): Similarly for PACK_INDEX_EXPR.
    
            * g++.dg/cpp26/pack-indexing9.C: Remove dg-sorry/dg-bogus, add
            tests for mangled names and further test coverage.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/mangle.cc                            | 35 ++++++++++++++++-------------
 gcc/testsuite/g++.dg/cpp26/pack-indexing9.C | 22 ++++++++++++++++--
 2 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 9eb09dcede75..d1301789ef4d 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -2745,16 +2745,19 @@ write_type (tree type)
 
            case PACK_INDEX_TYPE:
              /* https://github.com/itanium-cxx-abi/cxx-abi/issues/175.  */
+             write_string ("Dy");
              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_char ('J');
+                 for (int i = 0; i < TREE_VEC_LENGTH (PACK_INDEX_PACK (type));
+                      ++i)
+                   write_template_arg (TREE_VEC_ELT (PACK_INDEX_PACK (type),
+                                                     i));
+                 write_char ('E');
                }
-             write_string ("Dy");
-             /* Dy rather than DyDp.  */
-             write_type (PACK_EXPANSION_PATTERN (PACK_INDEX_PACK (type)));
+             else
+               /* Dy rather than DyDp.  */
+               write_type (PACK_EXPANSION_PATTERN (PACK_INDEX_PACK (type)));
              write_expression (PACK_INDEX_INDEX (type));
              break;
 
@@ -3614,17 +3617,19 @@ write_expression (tree expr)
   else if (code == PACK_INDEX_EXPR)
     {
       /* https://github.com/itanium-cxx-abi/cxx-abi/issues/175.  */
+      write_string ("sy");
       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));
+         write_char ('J');
+         for (int i = 0; i < TREE_VEC_LENGTH (PACK_INDEX_PACK (expr));
+              ++i)
+           write_template_arg (TREE_VEC_ELT (PACK_INDEX_PACK (expr), i));
+         write_char ('E');
        }
+      else
+       /* 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)
     {
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing9.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing9.C
index afd8a2f9ed6b..ab5d2c7704df 100644
--- a/gcc/testsuite/g++.dg/cpp26/pack-indexing9.C
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing9.C
@@ -4,24 +4,42 @@
 // From <https://github.com/itanium-cxx-abi/cxx-abi/issues/175>.
 
 template <class... T> struct tuple {
-  template <unsigned I> T...[I] get();  // { dg-bogus "sorry, unimplemented: 
mangling" "" { xfail *-*-* } }
+  template <unsigned I> T...[I] get();
 };
 
 int
 g ()
 {
   tuple<int> t;
+  // { dg-final { scan-assembler "_ZN5tupleIJiEE3getILj0EEEDyJiET_v" } }
   return t.get<0>();
 }
 
 template<typename T, typename U> concept C = true;
+template<typename T, auto U> concept D = true;
 template<typename ...T> struct A {
-    template<int I, typename ...U> void f(T...[I], U...[I]) requires 
C<T...[I], U...[I]>;  // { dg-message "sorry, unimplemented: mangling" }
+  template<int I, typename ...U> void f(T...[I], U...[I]) requires C<T...[I], 
U...[I]>;
+  template<int I, auto ...U> void h(T...[I], decltype(U...[I])) requires 
D<T...[I], U...[I]>;
 };
 
 void
 h ()
 {
   A<char, int, double> a;
+  // { dg-final { scan-assembler 
"_ZN1AIJcidEE1fILi1EJiicEEEvDyJcidET_DyT0_T_Q1CIDyT_TL0__DyTL0_0_TL0__E" } }
   a.f<1, int, int, char>(1, 2);
+  // { dg-final { scan-assembler 
"_ZN1AIJcidEE1hILi1EJLi2ELl3ELj4EEEEvDyJcidET_DtsyT0_T_EQ1DIDyT_TL0__XsyTL0_0_TL0__EE"
 } }
+  a.h<1, 2, 3L, 4U>(1, 3L);
+}
+
+template <auto... U> struct E {
+  template <unsigned I> decltype (U...[I]) get();
+};
+
+int
+i ()
+{
+  E<1, 2L, 3U, 4LL> t;
+  // { dg-final { scan-assembler 
"_ZN1EIJLi1ELl2ELj3ELx4EEE3getILj2EEEDtsyJLi1ELl2ELj3ELx4EET_Ev" } }
+  return t.get<2>();
 }

Reply via email to