aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/init.c57
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-value.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist53.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C2
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 "" }