Now that argument packs don't have a type, the check for a non-type argument with a typedefy type wasn't working for them. So let's recurse.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 7a163ab3c89382ad5c3bda2f345950760bc499c7 Author: Jason Merrill <ja...@redhat.com> Date: Fri Mar 9 21:56:18 2018 -0500 PR c++/84770 - ICE with typedef and parameter pack. * pt.c (verify_unstripped_args_1): Split out from verify_unstripped_args. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2d7ce6062a7..c53f0bc23bb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1133,27 +1133,32 @@ optimize_specialization_lookup_p (tree tmpl) /* Make sure ARGS doesn't use any inappropriate typedefs; we should have gone through coerce_template_parms by now. */ +static void +verify_unstripped_args_1 (tree inner) +{ + for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i) + { + tree arg = TREE_VEC_ELT (inner, i); + if (TREE_CODE (arg) == TEMPLATE_DECL) + /* OK */; + else if (TYPE_P (arg)) + gcc_assert (strip_typedefs (arg, NULL) == arg); + else if (ARGUMENT_PACK_P (arg)) + verify_unstripped_args_1 (ARGUMENT_PACK_ARGS (arg)); + else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg)) + /* Allow typedefs on the type of a non-type argument, since a + parameter can have them. */; + else + gcc_assert (strip_typedefs_expr (arg, NULL) == arg); + } +} + static void verify_unstripped_args (tree args) { ++processing_template_decl; if (!any_dependent_template_arguments_p (args)) - { - tree inner = INNERMOST_TEMPLATE_ARGS (args); - for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i) - { - tree arg = TREE_VEC_ELT (inner, i); - if (TREE_CODE (arg) == TEMPLATE_DECL) - /* OK */; - else if (TYPE_P (arg)) - gcc_assert (strip_typedefs (arg, NULL) == arg); - else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg)) - /* Allow typedefs on the type of a non-type argument, since a - parameter can have them. */; - else - gcc_assert (strip_typedefs_expr (arg, NULL) == arg); - } - } + verify_unstripped_args_1 (INNERMOST_TEMPLATE_ARGS (args)); --processing_template_decl; } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic173.C b/gcc/testsuite/g++.dg/cpp0x/variadic173.C new file mode 100644 index 00000000000..a0ca89b764f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic173.C @@ -0,0 +1,10 @@ +// PR c++/84770 +// { dg-do compile { target c++11 } } + +typedef int T; + +template<T&...> struct A {}; + +int i; + +A<i> a;