From: Jason Merrill Date: Thu, 4 Feb 2021 02:56:59 +0000 (-0500) Subject: c++: No aggregate CTAD with explicit dguide [PR98802] X-Git-Tag: releases/gcc-10.3.0~319 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96bff67d349b134dbcafc5c565ac3ce3a5cf544b;p=thirdparty%2Fgcc.git c++: No aggregate CTAD with explicit dguide [PR98802] 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. --- diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 26907615a514..0c53fd9933ad 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -28805,17 +28805,19 @@ static GTY((deletable)) hash_map *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 index 000000000000..651645486d22 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction78.C @@ -0,0 +1,20 @@ +// PR c++/98802 +// { dg-do compile { target c++17 } } + +using size_t = decltype(sizeof(42)); + +template +struct List { + T head; + List tail; +}; + +template +struct List {}; + +template List(T) -> List; +template List(T, List) -> List; + +int main() { + auto list2 = List{0, List{1, List{2}}}; +}