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>
PR c++/49216
* init.c (build_new_1): Pass {} down to build_vec_init.
(build_vec_init): Handle it.
DR 1207
PR c++/49003
* 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,
&& BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *init, 0))
&& CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *init, 0)))
{
tree arraytype, domain;
vecinit = VEC_index (tree, *init, 0);
if (TREE_CONSTANT (nelts))
domain = compute_array_index_type (NULL_TREE, nelts, complain);
if (CONSTRUCTOR_NELTS (vecinit) == 0)
/* List-value-initialization, leave it alone. */;
else
{
domain = NULL_TREE;
if (CONSTRUCTOR_NELTS (vecinit) > 0)
warning (0, "non-constant array size in new, unable to "
"verify length of initializer-list");
tree arraytype, domain;
if (TREE_CONSTANT (nelts))
domain = compute_array_index_type (NULL_TREE, nelts,
complain);
else
{
domain = NULL_TREE;
if (CONSTRUCTOR_NELTS (vecinit) > 0)
warning (0, "non-constant array size in new, unable "
"to verify length of initializer-list");
}
arraytype = build_cplus_array_type (type, domain);
vecinit = digest_init (arraytype, vecinit, complain);
}
arraytype = build_cplus_array_type (type, domain);
vecinit = digest_init (arraytype, vecinit, complain);
}
else if (*init)
{
if (complain & tf_error)
permerror (input_location, "ISO C++ forbids initialization in array new");
permerror (input_location,
"parenthesized initializer in array new");
else
return error_mark_node;
vecinit = build_tree_list_vec (*init);
......@@ -3090,9 +3097,23 @@ 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. */
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? */
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
brace-enclosed initializers. */
......@@ -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. */
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)
&& (num_initialized_elts
== tree_low_cst (maxindex, 0) + 1))))
......@@ -3276,8 +3297,16 @@ build_vec_init (tree base, tree maxindex, tree init,
}
else
{
gcc_assert (type_build_ctor_call (type));
elt_init = build_aggr_init (to, init, 0, complain);
gcc_assert (type_build_ctor_call (type) || init);
if (CLASS_TYPE_P (type))
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)
......
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
* g++.dg/cpp0x/trailing6.C: New.
* g++.dg/cpp0x/pr45908.C: No error.
......
......@@ -2,6 +2,9 @@
// { dg-options -std=c++0x }
// { 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
struct B {};
struct A: B {
......@@ -18,8 +21,14 @@ int main()
{
A a{};
C c;
int space = 42;
A* ap = new (&space) A{};
int space1[1] = { 42 };
A* a1p = new (space1) A[1]{};
if (a.i != 0
|| c.i != 0
|| ap->i != 0
|| a1p[0].i != 0
|| A{}.i != 0
|| f({}) != 0)
return 1;
......
......@@ -4,6 +4,7 @@
#include <initializer_list>
extern "C" void abort();
void * operator new[] (__SIZE_TYPE__, void *p) { return p; }
bool constructed;
......@@ -14,7 +15,8 @@ struct A
int main() {
new A[1]{};
int *p = new int[1]{};
int space[1] = { 42 };
int *p = new (space) int[1]{};
if (p[0] != 0 || !constructed)
abort();
}
// { dg-do run { xfail *-*-* } }
// { dg-do run }
// { dg-options "-w -fpermissive" }
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