]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: ICE when substituting packs into type aliases [PR118104]
authorMarek Polacek <polacek@redhat.com>
Mon, 17 Mar 2025 16:56:40 +0000 (12:56 -0400)
committerMarek Polacek <polacek@redhat.com>
Tue, 18 Mar 2025 20:09:04 +0000 (16:09 -0400)
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 <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C [new file with mode: 0644]

index 50eda189c43a1d02a8a12b5d8347410ad05aecb2..538ff220d745207555bfa035a33b5a0bf51c98d1 100644 (file)
@@ -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 (file)
index 0000000..077f033
--- /dev/null
@@ -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;
+}