diff mbox series

[pushed] c++: designated init cleanup [PR105925]

Message ID 20220623211707.182601-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: designated init cleanup [PR105925] | expand

Commit Message

Jason Merrill June 23, 2022, 9:17 p.m. UTC
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(-)


base-commit: d610ae121e8ecd738de4dc01e6ac11ecf7c2327e
diff mbox series

Patch

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