From 6c72f1bfc3469422460d86314a081353632d4bcb Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 23 Jun 2022 14:41:19 -0400 Subject: [PATCH] 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. --- gcc/cp/call.cc | 60 +++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 4710c3777c5..f1dd8377628 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -969,7 +969,8 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) tree empty_ctor = NULL_TREE; hash_set 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))