From: Jason Merrill Date: Sat, 2 Aug 2014 00:52:09 +0000 (-0400) Subject: re PR c++/60417 ([DR 1518] Bogus error on C++03 aggregate initialization) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3bc63227d5eb38a70adee7375e5d3596e9c7ec01;p=gcc.git re PR c++/60417 ([DR 1518] Bogus error on C++03 aggregate initialization) 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5d06ade76d6..dc4aebe9f50 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-08-01 Jason Merrill + + 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 DR 217 again diff --git a/gcc/cp/init.c b/gcc/cp/init.c index f8cae283383..eeee5bb3620 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 59a47605d6c..20523faf09b 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 00000000000..d1dbb39fc61 --- /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] = { }; +}