This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/60417 (explicit ctor vs aggregate init)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 01 Aug 2014 20:51:35 -0400
- Subject: Re: C++ PATCH for c++/60417 (explicit ctor vs aggregate init)
- Authentication-results: sourceware.org; auth=none
- References: <5316505A dot 1010901 at redhat dot com>
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] = { };
+}