diff options
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 57 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-value.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist53.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C | 2 |
6 files changed, 65 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c5751bd..e95e7c8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 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, diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ac2b733..f80c475 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index da5b817..7afaafb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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. diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-value.C b/gcc/testsuite/g++.dg/cpp0x/initlist-value.C index 25a3373..215bb90 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist-value.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-value.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist53.C b/gcc/testsuite/g++.dg/cpp0x/initlist53.C index 750ebba..22633f9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist53.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist53.C @@ -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(); } diff --git a/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C b/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C index 93d15d0..c6a967c 100644 --- a/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C +++ b/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C @@ -1,4 +1,4 @@ -// { dg-do run { xfail *-*-* } } +// { dg-do run } // { dg-options "-w -fpermissive" } int *foo = new int[1](42); // { dg-bogus "" } |