re PR c++/60417 ([DR 1518] Bogus error on C++03 aggregate initialization)
authorJason Merrill <jason@redhat.com>
Sat, 2 Aug 2014 00:52:09 +0000 (20:52 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 2 Aug 2014 00:52:09 +0000 (20:52 -0400)
PR c++/60417
* init.c (build_vec_init): Set CONSTRUCTOR_IS_DIRECT_INIT on
init-list for trailing elements.
* typeck2.c (process_init_constructor_array): Likewise.

From-SVN: r213511

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/init/explicit2.C [new file with mode: 0644]

index 5d06ade76d64db888b6a4b098e1e0cea24db7938..dc4aebe9f50504960a9065d76c371228dd08dfe3 100644 (file)
@@ -1,3 +1,10 @@
+2014-08-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/60417
+       * init.c (build_vec_init): Set CONSTRUCTOR_IS_DIRECT_INIT on
+       init-list for trailing elements.
+       * typeck2.c (process_init_constructor_array): Likewise.
+
 2014-08-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        DR 217 again
index f8cae283383dc49e75265afd2bb46f37d8d483ea..eeee5bb362033b7f0d06baa8467609e511c81cb1 100644 (file)
@@ -3545,19 +3545,11 @@ build_vec_init (tree base, tree maxindex, tree init,
       try_block = begin_try_block ();
     }
 
-  /* If the initializer is {}, then all elements are initialized from {}.
-     But for non-classes, that's the same as value-initialization.  */
+  bool empty_list = false;
   if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
       && CONSTRUCTOR_NELTS (init) == 0)
-    {
-      if (CLASS_TYPE_P (type))
-       /* Leave init alone.  */;
-      else
-       {
-         init = NULL_TREE;
-         explicit_value_init_p = true;
-       }
-    }
+    /* Skip over the handling of non-empty init lists.  */
+    empty_list = true;
 
   /* Maybe pull out constant value when from_array? */
 
@@ -3677,14 +3669,8 @@ build_vec_init (tree base, tree maxindex, tree init,
            vec_free (new_vec);
        }
 
-      /* Any elements without explicit initializers get {}.  */
-      if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
-       init = build_constructor (init_list_type_node, NULL);
-      else
-       {
-         init = NULL_TREE;
-         explicit_value_init_p = true;
-       }
+      /* Any elements without explicit initializers get T{}.  */
+      empty_list = true;
     }
   else if (from_array)
     {
@@ -3699,6 +3685,26 @@ build_vec_init (tree base, tree maxindex, tree init,
        }
     }
 
+  /* If the initializer is {}, then all elements are initialized from T{}.
+     But for non-classes, that's the same as value-initialization.  */
+  if (empty_list)
+    {
+      if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
+       {
+         if (BRACE_ENCLOSED_INITIALIZER_P (init)
+             && CONSTRUCTOR_NELTS (init) == 0)
+           /* Reuse it.  */;
+         else
+           init = build_constructor (init_list_type_node, NULL);
+         CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
+       }
+      else
+       {
+         init = NULL_TREE;
+         explicit_value_init_p = true;
+       }
+    }
+
   /* Now, default-initialize any remaining elements.  We don't need to
      do that if a) the type does not need constructing, or b) we've
      already initialized all the elements.
index 59a47605d6ca04a1dabfaab86d3acb399c5f344b..20523faf09b406bf053a8e61135767fdef5bcb30 100644 (file)
@@ -1239,8 +1239,9 @@ process_init_constructor_array (tree type, tree init,
          {
            /* 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 {}.  */
+              initialization explicit by list-initializing from T{}.  */
            next = build_constructor (init_list_type_node, NULL);
+           CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
            next = massage_init_elt (TREE_TYPE (type), next, complain);
            if (initializer_zerop (next))
              /* The default zero-initialization is fine for us; don't
diff --git a/gcc/testsuite/g++.dg/init/explicit2.C b/gcc/testsuite/g++.dg/init/explicit2.C
new file mode 100644 (file)
index 0000000..d1dbb39
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/60417
+
+struct A { explicit A(int = 0); };
+
+int main()
+{
+  A a[1] = { };
+}