c++: designated init cleanup [PR105925]

build_aggr_conv expects to run after reshape_init, which will usually have
filled out all the CONSTRUCTOR indexes; there's no reason to limit using
those to the case where the user gave an explicit designator.

	PR c++/105925

gcc/cp/ChangeLog:

	* call.cc (build_aggr_conv): Don't depend on
	CONSTRUCTOR_IS_DESIGNATED_INIT.
This commit is contained in:
Jason Merrill 2022-06-23 14:41:19 -04:00
parent d610ae121e
commit 6c72f1bfc3

View File

@ -969,7 +969,8 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
tree empty_ctor = NULL_TREE;
hash_set<tree, true> pset;
/* We already called reshape_init in implicit_conversion. */
/* We already called reshape_init in implicit_conversion, but it might not
have done anything in the case of parenthesized aggr init. */
/* The conversions within the init-list aren't affected by the enclosing
context; they're always simple copy-initialization. */
@ -979,49 +980,48 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
to corresponding TREE_TYPE (ce->index) and mark those FIELD_DECLs as
visited. In the following loop then ignore already visited
FIELD_DECLs. */
if (CONSTRUCTOR_IS_DESIGNATED_INIT (ctor))
tree idx, val;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, val)
{
tree idx, val;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, val)
if (!idx)
break;
gcc_checking_assert (TREE_CODE (idx) == FIELD_DECL);
tree ftype = TREE_TYPE (idx);
bool ok;
if (TREE_CODE (ftype) == ARRAY_TYPE)
ok = can_convert_array (ftype, val, flags, complain);
else
ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
complain);
if (!ok)
return NULL;
/* For unions, there should be just one initializer. */
if (TREE_CODE (type) == UNION_TYPE)
{
if (idx && TREE_CODE (idx) == FIELD_DECL)
{
tree ftype = TREE_TYPE (idx);
bool ok;
if (TREE_CODE (ftype) == ARRAY_TYPE)
ok = can_convert_array (ftype, val, flags, complain);
else
ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
complain);
if (!ok)
return NULL;
/* For unions, there should be just one initializer. */
if (TREE_CODE (type) == UNION_TYPE)
{
field = NULL_TREE;
i = 1;
break;
}
pset.add (idx);
}
else
return NULL;
field = NULL_TREE;
i = 1;
break;
}
pset.add (idx);
}
for (; field; field = next_aggregate_field (DECL_CHAIN (field)))
{
tree ftype = TREE_TYPE (field);
tree val;
bool ok;
if (!pset.is_empty () && field_in_pset (pset, field))
continue;
if (i < CONSTRUCTOR_NELTS (ctor))
{
val = CONSTRUCTOR_ELT (ctor, i)->value;
constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
gcc_checking_assert (!ce->index);
val = ce->value;
++i;
}
else if (DECL_INITIAL (field))