c++: placeholder type constraint and argument pack [PR99815]

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 in order to properly separate the implicit 'auto' argument
from the rest.

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.
This commit is contained in:
Patrick Palka 2021-03-30 22:54:37 -04:00
parent 08d2edae5d
commit 0bbf0edbfc
2 changed files with 37 additions and 0 deletions

View File

@ -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)

View File

@ -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;
}