On Wed, 2 Feb 2022, Jason Merrill wrote: > On 2/2/22 12:09, Patrick Palka wrote: > > The satisfaction cache needs to look through ARGUMENT_PACK_SELECT > > template arguments before calling iterative_hash_template_arg and > > template_args_equal, which would otherwise crash. > > Maybe we should handle ARGUMENT_PACK_SELECT in iterative_hash_template_arg and > template_args_equal, rather than their callers?
Like so? I can't think of a good reason not to handle ARGUMENT_PACK_SELECT ther, but FWIW it looks like we had such handling in the past, until it was removed in r7-2082. -- >8 -- Subject: [PATCH] c++: lambda in pack expansion using outer pack in constraint [PR103706] Here when expanding the pack expansion pattern, the template argument for T is an ARGUMENT_PACK_SELECT, which during satisfaction of C<T> the satisfaction cache passes to iterative_hash_template_arg and template_args_equal, which don't handle ARGUMENT_PACK_SELECT presumably because at some point it became unnecessary to do so. Since it now appears necessary again, this patch reinstates the ARGUMENT_PACK_SELECT handling that was removed by r7-2082. PR c++/103706 gcc/cp/ChangeLog: * pt.cc (iterative_hash_template_arg): Handle ARGUMENT_PACK_SELECT. (template_args_equal): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-lambda19.C: New test. --- gcc/cp/pt.cc | 10 ++++++---- gcc/testsuite/g++.dg/cpp2a/concepts-lambda19.C | 11 +++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-lambda19.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c62822d65f8..644f24b7c09 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -220,6 +220,7 @@ static tree make_argument_pack (tree); static void register_parameter_specializations (tree, tree); static tree enclosing_instantiation_of (tree tctx); static void instantiate_body (tree pattern, tree args, tree d, bool nested); +static tree argument_pack_select_arg (tree t); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -1783,6 +1784,9 @@ iterative_hash_template_arg (tree arg, hashval_t val) if (arg == NULL_TREE) return iterative_hash_object (arg, val); + if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT) + arg = argument_pack_select_arg (arg); + if (!TYPE_P (arg)) /* Strip nop-like things, but not the same as STRIP_NOPS. */ while (CONVERT_EXPR_P (arg) @@ -1796,9 +1800,6 @@ iterative_hash_template_arg (tree arg, hashval_t val) switch (code) { - case ARGUMENT_PACK_SELECT: - gcc_unreachable (); - case ERROR_MARK: return val; @@ -9246,7 +9247,8 @@ template_args_equal (tree ot, tree nt, bool partial_order /* = false */) else if (ARGUMENT_PACK_P (ot) || ARGUMENT_PACK_P (nt)) return cp_tree_equal (ot, nt); else if (TREE_CODE (ot) == ARGUMENT_PACK_SELECT) - gcc_unreachable (); + return template_args_equal (argument_pack_select_arg (ot), + argument_pack_select_arg (nt)); else if (TYPE_P (nt) || TYPE_P (ot)) { if (!(TYPE_P (nt) && TYPE_P (ot))) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda19.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda19.C new file mode 100644 index 00000000000..570e3596f1b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda19.C @@ -0,0 +1,11 @@ +// PR c++/103706 +// { dg-do compile { target c++20 } } + +template<class T> concept C = __is_same(T, int); + +template<class... T> void f() { + ([]() requires C<T> { return T(); }(), ...); // { dg-error "no match" } +} + +template void f<int, int, int>(); // { dg-bogus "" } +template void f<int, int, char>(); // { dg-message "required from here" } -- 2.35.0