95568 complains that CTAD for aggregates doesn't work within requires-clause and it turned out that it doesn't work when we try the deduction in a template. The reason is that maybe_aggr_guide creates a guide that can look like this
template<class T> X(decltype (X<T>::x))-> X<T> where the parameter is a decltype, which is a non-deduced context. So the subsequent build_new_function_call fails because unify_one_argument can't deduce anything from it ([temp.deduct.type]: "If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.") In such a case we probably want to return PTYPE and try again later like we do when trying to deduce from a type-dependent expression. Instead of playing with build_new_function_call with only tf_decltype or with uses_deducible_template_parms I'm only checking processing_template_decl because it's cheaper and because when we arein a template it seems pretty much guaranteed that the guide will have a DECLTYPE_TYPE parameter. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? gcc/cp/ChangeLog: PR c++/95568 * pt.c (do_class_deduction): When attempting CTAD for aggregates in a template, return PTYPE. gcc/testsuite/ChangeLog: PR c++/95568 * g++.dg/cpp2a/class-deduction-aggr5.C: New test. --- gcc/cp/pt.c | 9 ++++++++- .../g++.dg/cpp2a/class-deduction-aggr5.C | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr5.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 53a64c3a15e..1f6ad8289bd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -28830,7 +28830,14 @@ do_class_deduction (tree ptype, tree tmpl, tree init, } if (tree guide = maybe_aggr_guide (tmpl, init, args)) - cands = lookup_add (guide, cands); + { + /* In a template, GUIDE's type can have DECLTYPE_TYPE parameters + and those are non-deduced contexts. Wait until they have been + substituted. */ + if (processing_template_decl) + return ptype; + cands = lookup_add (guide, cands); + } tree call = error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr5.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr5.C new file mode 100644 index 00000000000..01253f42006 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr5.C @@ -0,0 +1,20 @@ +// PR c++/95568 +// { dg-do compile { target c++20 } } + +template<typename T> struct X { T x; }; +template<typename T, typename U> struct X2 { T x; U y; }; +template<typename T> concept Y = requires { X{0}; }; + +template<typename T> +void g() +{ + X{0}; + X2{1, 2.2}; + Y auto y = X{1}; +} + +void +fn () +{ + g<int>(); +} base-commit: 6b161257f9f8c7a26b7d119ebc32cbbc54d2e508 -- Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA