This testcase demonstrates we can legitimately enter satisfaction with an ARGUMENT_PACK_SELECT argument, which is problematic because we can't store such arguments in the satisfaction cache (or any other hash table).
Since this appears to be possible only during constrained auto deduction for a return-type-requirement, the most appropriate spot to fix this seems to be from do_auto_deduction, by calling preserve_args to strip A_P_S args before entering satisfaction. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/12? PR c++/105644 gcc/cp/ChangeLog: * pt.cc (do_auto_deduction): Call preserve_args before entering satisfaction for adc_requirement contexts. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires36.C: New test. --- gcc/cp/pt.cc | 6 ++++++ gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C | 12 ++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 4429ae66b68..821e0035c08 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -30965,6 +30965,12 @@ do_auto_deduction (tree type, tree init, tree auto_node, return type; } + /* We can see an ARGUMENT_PACK_SELECT argument when evaluating + a return-type-requirement. Get rid of them before entering + satisfaction, since the satisfaction cache can't handle them. */ + if (context == adc_requirement) + outer_targs = preserve_args (outer_targs); + if (context == adc_return_type || context == adc_variable_type || context == adc_decomp_type) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C new file mode 100644 index 00000000000..7d13b9b3e54 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires36.C @@ -0,0 +1,12 @@ +// PR c++/105644 +// { dg-do compile { target c++20 } } + +template<class T, class U> +concept same_as = __is_same(T, U); + +template<class... Ts> +concept C = (requires { { Ts() } -> same_as<Ts>; } && ...); + +static_assert(C<int, char>); +static_assert(!C<int, const char>); +static_assert(!C<const int, char>); -- 2.40.0.153.g6369acd968