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:
parent
e6cc67f661
commit
b1005f553d
@ -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
|
||||
|
20
gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr5.C
Normal file
20
gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr5.C
Normal 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>();
|
||||
}
|
35
gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr6.C
Normal file
35
gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr6.C
Normal 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>();
|
||||
}
|
Loading…
Reference in New Issue
Block a user