From: Patrick Palka Date: Wed, 31 Mar 2021 02:54:37 +0000 (-0400) Subject: c++: placeholder type constraint and argument pack [PR99815] X-Git-Tag: basepoints/gcc-12~337 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0bbf0edbfc782f8e4e416d5fbd1b52a515adb585;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a056ecefd1df..dc6f2f37f9bb 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 000000000000..eaea41a36eb6 --- /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 +struct is_same { static constexpr bool value = false; }; + +template +struct is_same { static constexpr bool value = true; }; + +template +concept C = is_same::value; // { dg-error "wrong number" } + +template void f() { + C auto x = 0; // { dg-error "constraints" } +} + +template void f(); // { dg-bogus "" } +template void f(); // { dg-message "required from here" } +template void f<>(); // { dg-message "required from here" } +template void f(); // { dg-message "required from here" } + +template void g() { + C auto x = 0; // { dg-error "constraints" } +} + +template void g<>(); // { dg-bogus "" } +template void g(); // { dg-message "required from here" } + +template void h() { + C auto x = 0; // { dg-error "constraints" } + C auto y = 0; +}