From: Jason Merrill Date: Thu, 23 Jun 2022 18:41:19 +0000 (-0400) Subject: c++: designated init cleanup [PR105925] X-Git-Tag: basepoints/gcc-14~5980 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c72f1bfc3469422460d86314a081353632d4bcb;p=thirdparty%2Fgcc.git 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. --- 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 && TREE_CODE (idx) == FIELD_DECL) - { - tree ftype = TREE_TYPE (idx); - bool ok; + if (!idx) + break; - 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); + gcc_checking_assert (TREE_CODE (idx) == FIELD_DECL); - 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; + 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); } 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))