]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: variadic class template placeholder deduction [PR97134]
authorPatrick Palka <ppalka@redhat.com>
Tue, 13 Apr 2021 03:22:03 +0000 (23:22 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 13 Apr 2021 03:22:03 +0000 (23:22 -0400)
do_class_deduction handles specially the case where we're deducing one
placeholder from another equivalent one, but here the initializer passed
to do_class_deduction is wrapped in an EXPR_PACK_EXPANSION (we're being
called from unify during get_partial_spec_bindings).  This patch makes
do_class_deduction look through EXPR_PACK_EXPANSIONs so that we detect
this case as well.

gcc/cp/ChangeLog:

PR c++/97134
* pt.c (do_class_deduction): Look through EXPR_PACK_EXPANSION
when checking if the initializer is an equivalent class
placeholder template parameter.

gcc/testsuite/ChangeLog:

PR c++/97134
* g++.dg/cpp2a/nontype-class43.C: New test.

gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp2a/nontype-class43.C [new file with mode: 0644]

index efcbc59f5c9814ea346568a0982329b298c4270f..6b63edda60d26a34f2507f3feec979c17f2a46b7 100644 (file)
@@ -29286,7 +29286,11 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
     return ptype;
 
   /* Initializing one placeholder from another.  */
-  if (init && TREE_CODE (init) == TEMPLATE_PARM_INDEX
+  if (init
+      && (TREE_CODE (init) == TEMPLATE_PARM_INDEX
+         || (TREE_CODE (init) == EXPR_PACK_EXPANSION
+             && (TREE_CODE (PACK_EXPANSION_PATTERN (init))
+                 == TEMPLATE_PARM_INDEX)))
       && is_auto (TREE_TYPE (init))
       && CLASS_PLACEHOLDER_TEMPLATE (TREE_TYPE (init)) == tmpl)
     return cp_build_qualified_type (TREE_TYPE (init), cp_type_quals (ptype));
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class43.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class43.C
new file mode 100644 (file)
index 0000000..f51684f
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/97134
+// { dg-do compile { target c++20 } }
+
+template<typename T>
+struct templ {};
+
+template<templ... Vs>
+struct wrapper {};
+
+template<templ... Vs> requires true
+struct wrapper<Vs...> {};