c++: Fix CTAD for aggregates in template [PR95568]

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.")

Those decltypes come from finish_decltype_type.  We can just use
TREE_TYPE instead.  I pondered using unlowered_expr_type, but that
didn't make any difference for the FIELD_DECLs I saw in
class-deduction-aggr6.C.

gcc/cp/ChangeLog:

	PR c++/95568
	* pt.c (collect_ctor_idx_types): Use TREE_TYPE.

gcc/testsuite/ChangeLog:

	PR c++/95568
	* g++.dg/cpp2a/class-deduction-aggr5.C: New test.
	* g++.dg/cpp2a/class-deduction-aggr6.C: New test.
This commit is contained in:
Marek Polacek 2020-06-23 18:07:34 -04:00
parent e6cc67f661
commit b1005f553d
3 changed files with 56 additions and 1 deletions

View File

@ -28329,7 +28329,7 @@ collect_ctor_idx_types (tree ctor, tree list, tree elt = NULL_TREE)
tree idx, val; unsigned i;
FOR_EACH_CONSTRUCTOR_ELT (v, i, idx, val)
{
tree ftype = elt ? elt : finish_decltype_type (idx, true, tf_none);
tree ftype = elt ? elt : TREE_TYPE (idx);
if (BRACE_ENCLOSED_INITIALIZER_P (val)
&& CONSTRUCTOR_NELTS (val)
/* As in reshape_init_r, a non-aggregate or array-of-dependent-bound

View File

@ -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>();
}

View File

@ -0,0 +1,35 @@
// PR c++/95568
// { dg-do compile { target c++20 } }
// CTAD with aggregates containing bit-fields.
template<class, class> struct same_type;
template<class T> struct same_type<T, T> {};
enum E { e };
enum class F { f };
template<typename T>
struct X {
T a : 5;
};
template<typename>
void g()
{
auto x = X{ 0 };
same_type<decltype(x.a), int>();
auto x2 = X{ E::e };
same_type<decltype(x2.a), E>();
auto x3 = X{ false };
same_type<decltype(x3.a), bool>();
auto x4 = X{ 0u };
same_type<decltype(x4.a), unsigned int>();
auto x5 = X{ F::f };
same_type<decltype(x5.a), F>();
}
void
fn ()
{
g<int>();
}