[pushed] c++: clarify reshape_init designator handling

Jason Merrill <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

While looking at r17-3010, I found the handling of designators in
reshape_init* unclear, particularly in reshape_init_r.  Jakub's patch
recurses directly from reshape_init_class to itself to avoid this confusion.

With this patch, if we see a designator in reshape_init_r, it designates a
member of TYPE, which means brace elision if !first_initializer_p.  For this
to be true I needed to adjust reshape_init_array_1 to use
reshape_single_init from c++/103337.  And then if we see a designator and
TYPE is a class or array, we know we're initializing an element so we don't
consider initializing TYPE directly.

gcc/cp/ChangeLog:

	* decl.cc (reshape_single_init): Declare sooner.
	(reshape_init_array_1): Use it.
	(reshape_init_class): Drop "subclass" case.
	(reshape_init_r): d->cur->index always means initializing
	an element.
---
 gcc/cp/decl.cc | 50 ++++++++++++++++++++++++--------------------------
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index cb3eb74c3a1..cd533217ec4 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -7477,6 +7477,7 @@ struct reshape_iter
 };
 
 static tree reshape_init_r (tree, reshape_iter *, tree, tsubst_flags_t);
+static tree reshape_single_init (tree, tree, tsubst_flags_t);
 
 /* FIELD is an element of TYPE_FIELDS or NULL.  In the former case, the value
    returned is the next FIELD_DECL (possibly FIELD itself) that can be
@@ -7663,6 +7664,11 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
 	    }
 	  TREE_TYPE (elt_init) = elt_type;
 	}
+      else if (d->cur->index)
+	{
+	  elt_init = reshape_single_init (elt_type, d->cur->value, complain);
+	  d->cur++;
+	}
       else
 	elt_init = reshape_init_r (elt_type, d,
 				   /*first_initializer_p=*/NULL_TREE,
@@ -7860,7 +7866,6 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
       constructor_elt *old_cur = d->cur;
       unsigned old_raw_idx = d->raw_idx;
       bool direct_desig = false;
-      bool subclass = false;
 
       /* Handle C++20 designated initializers.  */
       if (d->cur->index)
@@ -8020,7 +8025,6 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
 	      gcc_assert (aafield);
 	      field = aafield;
 	      direct_desig = false;
-	      subclass = true;
 	    }
 	}
 
@@ -8052,18 +8056,6 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
 					    d->cur->value, complain);
 	  d->cur++;
 	}
-      else if (subclass)
-	{
-	  if (complain & tf_warning)
-	    warning (OPT_Wmissing_braces,
-		     "missing braces around initializer for %qT",
-		     TREE_TYPE (field));
-	  field_init = reshape_init_class (TREE_TYPE (field), d,
-					   /*first_initializer_p=*/NULL_TREE,
-					   complain);
-	  if (TREE_CODE (field_init) == CONSTRUCTOR)
-	    CONSTRUCTOR_BRACES_ELIDED_P (field_init) = true;
-	}
       else
 	field_init = reshape_init_r (TREE_TYPE (field), d,
 				     /*first_initializer_p=*/NULL_TREE,
@@ -8189,6 +8181,21 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
       return init;
     }
 
+  /* If we have a designator, d doesn't initialize TYPE directly, it
+     initializes an element, with brace elision if !first_initializer_p.  But
+     if TYPE is non-aggregate (and we didn't already return error_mark_node),
+     we should have errored about the designator in has_designator_problem, so
+     now ignore it for error recovery.  */
+  if (d->cur->index)
+    {
+      /* Deliberately not CP_AGGREGATE_TYPE_P to get a better diagnostic for
+	 trying to designate a member of a non-aggregate class.  */
+      if (AGGREGATE_TYPE_P (type))
+	goto skip_single;
+      else
+	gcc_checking_assert (seen_error ());
+    }
+
   /* A non-aggregate type is always initialized with a single
      initializer.  */
   if (!CP_AGGREGATE_TYPE_P (type)
@@ -8239,8 +8246,6 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
      initialized from that element."  Even if T is an aggregate.  */
   if (cxx_dialect >= cxx11 && (CLASS_TYPE_P (type) || VECTOR_TYPE_P (type))
       && first_initializer_p
-      /* But not if it's a designated init.  */
-      && !d->cur->index
       && d->end - d->cur == 1
       && TREE_CODE (init) != RAW_DATA_CST
       && reference_related_p (type, TREE_TYPE (init)))
@@ -8273,6 +8278,8 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
 			      LOOKUP_NORMAL, complain)))
     return consume_init (init, d);
 
+ skip_single:
+
   /* [dcl.init.string]
 
       A char array (whether plain char, signed char, or unsigned char)
@@ -8317,7 +8324,7 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
   bool braces_elided_p = false;
   if (!first_initializer_p)
     {
-      if (TREE_CODE (stripped_init) == CONSTRUCTOR)
+      if (TREE_CODE (stripped_init) == CONSTRUCTOR && !d->cur->index)
 	{
 	  tree init_type = TREE_TYPE (init);
 	  if (init_type && TYPE_PTRMEMFUNC_P (init_type))
@@ -8330,15 +8337,6 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
 	     to handle initialization of arrays and similar.  */
 	  else if (COMPOUND_LITERAL_P (stripped_init))
 	    gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
-	  /* If we have an unresolved designator, we need to find the member it
-	     designates within TYPE, so proceed to the routines below.  For
-	     FIELD_DECL or INTEGER_CST designators, we're already initializing
-	     the designated element.  */
-	  else if (d->cur->index
-		   && TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
-	    /* Brace elision with designators is only permitted for anonymous
-	       aggregates.  */
-	    gcc_checking_assert (ANON_AGGR_TYPE_P (type));
 	  /* A CONSTRUCTOR of the target's type is a previously
 	     digested initializer.  */
 	  else if (same_type_ignoring_top_level_qualifiers_p (type, init_type))

base-commit: 3e43b55eb8fb520b6ed161697249fcef6699d11b
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.