This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH for c++/60417 (explicit ctor vs aggregate init)


On 03/04/2014 05:14 PM, Jason Merrill wrote:
In C++11, copy-list-initialization by explicit constructor is an error,
even for the default constructor.  But this combined with the change of
aggregate initialization to use {} for any missing initializers means
that well-formed C++03 code becomes ill-formed in C++11.  Until the
committee decides what to do about this, let's call the implicit
initializers direct-initialization.

...and for array initialization as well.

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


commit ef09581840cc49d85599a2a9f2c855d8c8b60d9f
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Aug 1 16:13:54 2014 -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.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index f8cae28..eeee5bb3 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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.
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 59a4760..20523fa 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 0000000..d1dbb39
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/explicit2.C
@@ -0,0 +1,8 @@
+// PR c++/60417
+
+struct A { explicit A(int = 0); };
+
+int main()
+{
+  A a[1] = { };
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]