When checking dependence of a placeholder type constraint, if the first template argument of the constraint is an argument pack, we need to expand it so that we properly separate the implicit 'auto' argument from the rest.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? gcc/cp/ChangeLog: PR c++/99815 * pt.c (placeholder_type_constraint_dependent_p): Expand argument packs to separate the first non-pack argument from the rest. gcc/testsuite/ChangeLog: PR c++/99815 * g++.dg/cpp2a/concepts-placeholder5.C: New test. --- gcc/cp/pt.c | 5 +++ .../g++.dg/cpp2a/concepts-placeholder5.C | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder5.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a056ecefd1d..dc6f2f37f9b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -28189,6 +28189,11 @@ placeholder_type_constraint_dependent_p (tree t) tree id = unpack_concept_check (t); tree args = TREE_OPERAND (id, 1); tree first = TREE_VEC_ELT (args, 0); + if (ARGUMENT_PACK_P (first)) + { + args = expand_template_argument_pack (args); + first = TREE_VEC_ELT (args, 0); + } gcc_checking_assert (TREE_CODE (first) == WILDCARD_DECL || is_auto (first)); for (int i = 1; i < TREE_VEC_LENGTH (args); ++i) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder5.C new file mode 100644 index 00000000000..eaea41a36eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder5.C @@ -0,0 +1,32 @@ +// PR c++/99815 +// { dg-do compile { target c++20 } } + +template <class T, class U> +struct is_same { static constexpr bool value = false; }; + +template <class T> +struct is_same<T, T> { static constexpr bool value = true; }; + +template <class... Ts> +concept C = is_same<Ts...>::value; // { dg-error "wrong number" } + +template <class... Ts> void f() { + C<Ts...> auto x = 0; // { dg-error "constraints" } +} + +template void f<int>(); // { dg-bogus "" } +template void f<char>(); // { dg-message "required from here" } +template void f<>(); // { dg-message "required from here" } +template void f<int, int>(); // { dg-message "required from here" } + +template <class... Ts> void g() { + C<Ts..., int> auto x = 0; // { dg-error "constraints" } +} + +template void g<>(); // { dg-bogus "" } +template void g<int>(); // { dg-message "required from here" } + +template <class> void h() { + C<char> auto x = 0; // { dg-error "constraints" } + C<int> auto y = 0; +} -- 2.31.1.133.g84d06cdc06