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
This commit is contained in:
Jason Merrill 2014-08-01 20:52:09 -04:00 committed by Jason Merrill
parent f42589ed15
commit 3bc63227d5
4 changed files with 42 additions and 20 deletions

View 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> 2014-08-01 Paolo Carlini <paolo.carlini@oracle.com>
DR 217 again DR 217 again

View File

@ -3545,19 +3545,11 @@ build_vec_init (tree base, tree maxindex, tree init,
try_block = begin_try_block (); try_block = begin_try_block ();
} }
/* If the initializer is {}, then all elements are initialized from {}. bool empty_list = false;
But for non-classes, that's the same as value-initialization. */
if (init && BRACE_ENCLOSED_INITIALIZER_P (init) if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CONSTRUCTOR_NELTS (init) == 0) && CONSTRUCTOR_NELTS (init) == 0)
{ /* Skip over the handling of non-empty init lists. */
if (CLASS_TYPE_P (type)) empty_list = true;
/* Leave init alone. */;
else
{
init = NULL_TREE;
explicit_value_init_p = true;
}
}
/* Maybe pull out constant value when from_array? */ /* 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); vec_free (new_vec);
} }
/* Any elements without explicit initializers get {}. */ /* Any elements without explicit initializers get T{}. */
if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) empty_list = true;
init = build_constructor (init_list_type_node, NULL);
else
{
init = NULL_TREE;
explicit_value_init_p = true;
}
} }
else if (from_array) 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 /* 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 do that if a) the type does not need constructing, or b) we've
already initialized all the elements. already initialized all the elements.

View File

@ -1239,8 +1239,9 @@ process_init_constructor_array (tree type, tree init,
{ {
/* If this type needs constructors run for default-initialization, /* 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 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); next = build_constructor (init_list_type_node, NULL);
CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
next = massage_init_elt (TREE_TYPE (type), next, complain); next = massage_init_elt (TREE_TYPE (type), next, complain);
if (initializer_zerop (next)) if (initializer_zerop (next))
/* The default zero-initialization is fine for us; don't /* The default zero-initialization is fine for us; don't

View File

@ -0,0 +1,8 @@
// PR c++/60417
struct A { explicit A(int = 0); };
int main()
{
A a[1] = { };
}