]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: No aggregate CTAD with explicit dguide [PR98802]
authorJason Merrill <jason@redhat.com>
Thu, 4 Feb 2021 02:56:59 +0000 (21:56 -0500)
committerJason Merrill <jason@redhat.com>
Thu, 4 Feb 2021 06:46:47 +0000 (01:46 -0500)
In my implementation of P2082R1 I missed this piece: the aggregate deduction
candidate is not generated if the class has user-written deduction guides.

gcc/cp/ChangeLog:

PR c++/98802
* pt.c (deduction_guides_for): Add any_dguides_p parm.
(do_class_deduction): No aggregate guide if any_dguides_p.

gcc/testsuite/ChangeLog:

PR c++/98802
* g++.dg/cpp1z/class-deduction78.C: New test.

gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1z/class-deduction78.C [new file with mode: 0644]

index 26907615a5146e4b50589ae8d9f4d43376fdd029..0c53fd9933ad9eda02c7777b89fac84c269e2cce 100644 (file)
@@ -28805,17 +28805,19 @@ static GTY((deletable)) hash_map<tree, tree_pair_p> *dguide_cache;
 
 /* Return the non-aggregate deduction guides for deducible template TMPL.  The
    aggregate candidate is added separately because it depends on the
-   initializer.  */
+   initializer.  Set ANY_DGUIDES_P if we find a non-implicit deduction
+   guide.  */
 
 static tree
-deduction_guides_for (tree tmpl, tsubst_flags_t complain)
+deduction_guides_for (tree tmpl, bool &any_dguides_p, tsubst_flags_t complain)
 {
   tree guides = NULL_TREE;
   if (DECL_ALIAS_TEMPLATE_P (tmpl))
     {
       tree under = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
       tree tinfo = get_template_info (under);
-      guides = deduction_guides_for (TI_TEMPLATE (tinfo), complain);
+      guides = deduction_guides_for (TI_TEMPLATE (tinfo), any_dguides_p,
+                                    complain);
     }
   else
     {
@@ -28825,6 +28827,8 @@ deduction_guides_for (tree tmpl, tsubst_flags_t complain)
                                      /*hidden*/false);
       if (guides == error_mark_node)
        guides = NULL_TREE;
+      else
+       any_dguides_p = true;
     }
 
   /* Cache the deduction guides for a template.  We also remember the result of
@@ -28952,7 +28956,8 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
   if (args == NULL)
     return error_mark_node;
 
-  tree cands = deduction_guides_for (tmpl, complain);
+  bool any_dguides_p = false;
+  tree cands = deduction_guides_for (tmpl, any_dguides_p, complain);
   if (cands == error_mark_node)
     return error_mark_node;
 
@@ -28976,8 +28981,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
        }
     }
 
-  if (tree guide = maybe_aggr_guide (tmpl, init, args))
-    cands = lookup_add (guide, cands);
+  if (!any_dguides_p)
+    if (tree guide = maybe_aggr_guide (tmpl, init, args))
+      cands = lookup_add (guide, cands);
 
   tree call = error_mark_node;
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction78.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction78.C
new file mode 100644 (file)
index 0000000..6516454
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/98802
+// { dg-do compile { target c++17 } }
+
+using size_t = decltype(sizeof(42));
+
+template<typename T, size_t N = 0>
+struct List {
+    T head;
+    List<T, N-1> tail;
+};
+
+template<typename T>
+struct List<T, 0> {};
+
+template<typename T> List(T) -> List<T, 1>;
+template<typename T, size_t N> List(T, List<T, N>) -> List<T, N+1>;
+
+int main() {
+  auto list2 = List{0, List{1, List{2}}};
+}