https://gcc.gnu.org/g:6751bd4ac48a8529e2476a6848a77e81de540814

commit r15-8278-g6751bd4ac48a8529e2476a6848a77e81de540814
Author: Marek Polacek <pola...@redhat.com>
Date:   Mon Mar 17 12:56:40 2025 -0400

    c++: ICE when substituting packs into type aliases [PR118104]
    
    r12-1094 mentions that adding the assert didn't lead to any regressions
    in the testsuite, but this test case demonstrates that we can reach it
    with valid code.
    
    Here we arrive in use_pack_expansion_extra_args_p with t which is an
    expansion whose pattern is void(Ts, Us) and tparm packs are {Us, Ts},
    and parm_packs is { Ts -> <int, int>, Us -> <A, P...> }.  We want to
    expand the pack into void(int, A) and void(int, P...).  We compare
    int to A, which is fine, but then int to P... which crashes.  But
    the code is valid so this patch removes the assert.
    
            PR c++/118104
    
    gcc/cp/ChangeLog:
    
            * pt.cc (use_pack_expansion_extra_args_p): Remove an assert.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/alias-decl-variadic3.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/pt.cc                                      | 11 ++++++++++-
 gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C | 22 ++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 50eda189c43a..538ff220d745 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13180,7 +13180,16 @@ use_pack_expansion_extra_args_p (tree t,
 
       if (has_expansion_arg && has_non_expansion_arg)
        {
-         gcc_checking_assert (false);
+         /* We can get here with:
+
+             template <class... Ts> struct X {
+               template <class... Us> using Y = Z<void(Ts, Us)...>;
+             };
+             template <class A, class... P>
+             using foo = X<int, int>::Y<A, P...>;
+
+            where we compare int and A and then the second int and P...,
+            whose expansion-ness doesn't match, but that's OK.  */
          return true;
        }
     }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C 
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C
new file mode 100644
index 000000000000..077f033d545e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C
@@ -0,0 +1,22 @@
+// PR c++/118104
+// { dg-do compile { target c++11 } }
+
+template<typename... Zs> struct Z { };
+
+template <class... Ts> struct X {
+  template <class... Us> using W = Z<void(Ts, Us)...>;
+  template <class... Us> using Y = X<void(Ts, Us)...>;
+};
+
+template <class A, class... P>
+using foo = X<int, int>::W<A, P...>;
+
+template <class A, class... P>
+using bar = X<int, int>::Y<A, P...>;
+
+void
+g ()
+{
+  foo<int, int> f;
+  bar<int, int> b;
+}

Reply via email to