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.

Tested x86_64-pc-linux-gnu, applying to trunk.

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

base-commit: d610ae121e8ecd738de4dc01e6ac11ecf7c2327e
-- 
2.27.0

Reply via email to