On 2/3/22 12:04, Patrick Palka wrote:
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.

Ah, right.  That came after my fix for 67164,

https://gcc.gnu.org/pipermail/gcc-patches/2016-March/443660.html

with that PR, we were seeing ARGUMENT_PACK_SELECT unexpectedly because of excessive sharing of template argument lists. Why are we seeing it in satisfaction?

I should have commented the gcc_unreachables better.

-- >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" }

Reply via email to