Commit 1f65a8c8 by Jason Merrill Committed by Jason Merrill

re PR c++/49216 ([C++0x] ICE on compiling new-expression with braced-init-list for arrays)

	PR c++/49216
	* init.c (build_new_1): Pass {} down to build_vec_init.
	(build_vec_init): Handle it.

From-SVN: r175674
parent 417ae187
2011-06-29 Jason Merrill <jason@redhat.com> 2011-06-29 Jason Merrill <jason@redhat.com>
PR c++/49216
* init.c (build_new_1): Pass {} down to build_vec_init.
(build_vec_init): Handle it.
DR 1207 DR 1207
PR c++/49003 PR c++/49003
* cp-tree.h (struct saved_scope): Add x_current_class_ptr, * cp-tree.h (struct saved_scope): Add x_current_class_ptr,
......
...@@ -2396,24 +2396,31 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, ...@@ -2396,24 +2396,31 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
&& BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *init, 0)) && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *init, 0))
&& CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *init, 0))) && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *init, 0)))
{ {
tree arraytype, domain;
vecinit = VEC_index (tree, *init, 0); vecinit = VEC_index (tree, *init, 0);
if (CONSTRUCTOR_NELTS (vecinit) == 0)
/* List-value-initialization, leave it alone. */;
else
{
tree arraytype, domain;
if (TREE_CONSTANT (nelts)) if (TREE_CONSTANT (nelts))
domain = compute_array_index_type (NULL_TREE, nelts, complain); domain = compute_array_index_type (NULL_TREE, nelts,
complain);
else else
{ {
domain = NULL_TREE; domain = NULL_TREE;
if (CONSTRUCTOR_NELTS (vecinit) > 0) if (CONSTRUCTOR_NELTS (vecinit) > 0)
warning (0, "non-constant array size in new, unable to " warning (0, "non-constant array size in new, unable "
"verify length of initializer-list"); "to verify length of initializer-list");
} }
arraytype = build_cplus_array_type (type, domain); arraytype = build_cplus_array_type (type, domain);
vecinit = digest_init (arraytype, vecinit, complain); vecinit = digest_init (arraytype, vecinit, complain);
} }
}
else if (*init) else if (*init)
{ {
if (complain & tf_error) if (complain & tf_error)
permerror (input_location, "ISO C++ forbids initialization in array new"); permerror (input_location,
"parenthesized initializer in array new");
else else
return error_mark_node; return error_mark_node;
vecinit = build_tree_list_vec (*init); vecinit = build_tree_list_vec (*init);
...@@ -3090,9 +3097,23 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3090,9 +3097,23 @@ 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 {}.
But for non-classes, that's the same as value-initialization. */
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;
}
}
/* Maybe pull out constant value when from_array? */ /* Maybe pull out constant value when from_array? */
if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR) else if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
{ {
/* Do non-default initialization of non-trivial arrays resulting from /* Do non-default initialization of non-trivial arrays resulting from
brace-enclosed initializers. */ brace-enclosed initializers. */
...@@ -3210,7 +3231,7 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3210,7 +3231,7 @@ build_vec_init (tree base, tree maxindex, tree init,
We do need to keep going if we're copying an array. */ We do need to keep going if we're copying an array. */
if (from_array if (from_array
|| ((type_build_ctor_call (type) || explicit_value_init_p) || ((type_build_ctor_call (type) || init || explicit_value_init_p)
&& ! (host_integerp (maxindex, 0) && ! (host_integerp (maxindex, 0)
&& (num_initialized_elts && (num_initialized_elts
== tree_low_cst (maxindex, 0) + 1)))) == tree_low_cst (maxindex, 0) + 1))))
...@@ -3276,8 +3297,16 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3276,8 +3297,16 @@ build_vec_init (tree base, tree maxindex, tree init,
} }
else else
{ {
gcc_assert (type_build_ctor_call (type)); gcc_assert (type_build_ctor_call (type) || init);
if (CLASS_TYPE_P (type))
elt_init = build_aggr_init (to, init, 0, complain); elt_init = build_aggr_init (to, init, 0, complain);
else
{
if (TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init, ELK_INIT,
complain);
elt_init = build2 (INIT_EXPR, type, to, init);
}
} }
if (elt_init == error_mark_node) if (elt_init == error_mark_node)
......
2011-06-29 Jason Merrill <jason@redhat.com> 2011-06-29 Jason Merrill <jason@redhat.com>
PR c++/49216
* g++.dg/cpp0x/initlist53.C: Use placement new.
* g++.dg/cpp0x/initlist-value.C: Use placement new.
* g++.old-deja/g++.ext/arrnew2.C: Remove xfail.
PR c++/49003 PR c++/49003
* g++.dg/cpp0x/trailing6.C: New. * g++.dg/cpp0x/trailing6.C: New.
* g++.dg/cpp0x/pr45908.C: No error. * g++.dg/cpp0x/pr45908.C: No error.
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
// { dg-options -std=c++0x } // { dg-options -std=c++0x }
// { dg-do run } // { dg-do run }
void * operator new (__SIZE_TYPE__, void *p) { return p; }
void * operator new[] (__SIZE_TYPE__, void *p) { return p; }
// Empty base so A isn't an aggregate // Empty base so A isn't an aggregate
struct B {}; struct B {};
struct A: B { struct A: B {
...@@ -18,8 +21,14 @@ int main() ...@@ -18,8 +21,14 @@ int main()
{ {
A a{}; A a{};
C c; C c;
int space = 42;
A* ap = new (&space) A{};
int space1[1] = { 42 };
A* a1p = new (space1) A[1]{};
if (a.i != 0 if (a.i != 0
|| c.i != 0 || c.i != 0
|| ap->i != 0
|| a1p[0].i != 0
|| A{}.i != 0 || A{}.i != 0
|| f({}) != 0) || f({}) != 0)
return 1; return 1;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <initializer_list> #include <initializer_list>
extern "C" void abort(); extern "C" void abort();
void * operator new[] (__SIZE_TYPE__, void *p) { return p; }
bool constructed; bool constructed;
...@@ -14,7 +15,8 @@ struct A ...@@ -14,7 +15,8 @@ struct A
int main() { int main() {
new A[1]{}; new A[1]{};
int *p = new int[1]{}; int space[1] = { 42 };
int *p = new (space) int[1]{};
if (p[0] != 0 || !constructed) if (p[0] != 0 || !constructed)
abort(); abort();
} }
// { dg-do run { xfail *-*-* } } // { dg-do run }
// { dg-options "-w -fpermissive" } // { dg-options "-w -fpermissive" }
int *foo = new int[1](42); // { dg-bogus "" } int *foo = new int[1](42); // { dg-bogus "" }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment