On 01/15/2014 02:08 PM, Jason Merrill wrote:
1) Because atomics do have user-provided constructors, we were going
down the constructor path and not realizing that it just gave us
zero-initialization.  Fixed by calling maybe_constant_value and avoiding
adding extra zero-initialization to the end of the CONSTRUCTOR.

2) If we aren't dealing with zero-initialization, when we
value-initialize a bunch of elements at the end of an array, we really
ought to use a loop rather than initializing them individually.  Fixed
by using RANGE_EXPR and build_vec_init.

We really aren't ready to use RANGE_EXPR, as it turns out; a lot of places need to be changed to handle it, and this doesn't seem like the time in the development cycle for that sort of change. So I'm reverting #2 until the next stage 1, to fix c++/59886.


commit c3a3e3bd9f8a4f03cd79b706d8005ca2f4c02cd1
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Jan 23 15:51:05 2014 -0500

    	PR c++/59886
    	PR c++/59659
    	* typeck2.c (process_init_constructor_array): Don't create
    	RANGE_EXPR yet.

diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 897570a..a3fe2e3 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1201,42 +1201,40 @@ process_init_constructor_array (tree type, tree init,
       flags |= picflag_from_initializer (ce->value);
     }
 
-  /* No more initializers. If the array is unbounded, or we've initialized
-     all the elements, we are done. Otherwise, we must add initializers
-     ourselves.  */
-  if (!unbounded && i < len)
-    {
-      tree next;
+  /* No more initializers. If the array is unbounded, we are done. Otherwise,
+     we must add initializers ourselves.  */
+  if (!unbounded)
+    for (; i < len; ++i)
+      {
+	tree next;
 
-      if (type_build_ctor_call (TREE_TYPE (type)))
-	{
-	  /* If this type needs constructors run for default-initialization,
-	     we can't rely on the back end to do it for us, so make the
-	     initialization explicit by list-initializing from {}.  */
-	  next = build_constructor (init_list_type_node, NULL);
-	  next = massage_init_elt (TREE_TYPE (type), next, complain);
-	  if (initializer_zerop (next))
-	    /* The default zero-initialization is fine for us; don't
-	       add anything to the CONSTRUCTOR.  */
-	    next = NULL_TREE;
-	}
-      else if (!zero_init_p (TREE_TYPE (type)))
-	next = build_zero_init (TREE_TYPE (type),
-				/*nelts=*/NULL_TREE,
-				/*static_storage_p=*/false);
-      else
-	/* The default zero-initialization is fine for us; don't
-	   add anything to the CONSTRUCTOR.  */
-	next = NULL_TREE;
+	if (type_build_ctor_call (TREE_TYPE (type)))
+	  {
+	    /* If this type needs constructors run for default-initialization,
+	       we can't rely on the back end to do it for us, so make the
+	       initialization explicit by list-initializing from {}.  */
+	    next = build_constructor (init_list_type_node, NULL);
+	    next = massage_init_elt (TREE_TYPE (type), next, complain);
+	    if (initializer_zerop (next))
+	      /* The default zero-initialization is fine for us; don't
+		 add anything to the CONSTRUCTOR.  */
+	      next = NULL_TREE;
+	  }
+	else if (!zero_init_p (TREE_TYPE (type)))
+	  next = build_zero_init (TREE_TYPE (type),
+				  /*nelts=*/NULL_TREE,
+				  /*static_storage_p=*/false);
+	else
+	  /* The default zero-initialization is fine for us; don't
+	     add anything to the CONSTRUCTOR.  */
+	  next = NULL_TREE;
 
-      if (next)
-	{
-	  flags |= picflag_from_initializer (next);
-	  tree index = build2 (RANGE_EXPR, sizetype, size_int (i),
-			       size_int (len - 1));
-	  CONSTRUCTOR_APPEND_ELT (v, index, next);
-	}
-    }
+	if (next)
+	  {
+	    flags |= picflag_from_initializer (next);
+	    CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
+	  }
+      }
 
   CONSTRUCTOR_ELTS (init) = v;
   return flags;
diff --git a/gcc/testsuite/g++.dg/init/aggr10.C b/gcc/testsuite/g++.dg/init/aggr10.C
new file mode 100644
index 0000000..e494e20
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/aggr10.C
@@ -0,0 +1,6 @@
+// PR c++/59886
+
+struct A { A (); ~A (); };
+struct B { A b[4]; };
+struct C { B c[5]; };
+const C e = {};

Reply via email to