[gcc r11-7920] c++: placeholder type constraint and argument pack [PR99815]

Patrick Palka ppalka@gcc.gnu.org
Wed Mar 31 02:58:34 GMT 2021


https://gcc.gnu.org/g:0bbf0edbfc782f8e4e416d5fbd1b52a515adb585

commit r11-7920-g0bbf0edbfc782f8e4e416d5fbd1b52a515adb585
Author: Patrick Palka <ppalka@redhat.com>
Date:   Tue Mar 30 22:54:37 2021 -0400

    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:
---
 gcc/cp/pt.c                                        |  5 ++++
 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder5.C | 32 ++++++++++++++++++++++
 2 files changed, 37 insertions(+)

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


More information about the Gcc-cvs mailing list