diff options
author | Jason Merrill <jason@redhat.com> | 2008-07-31 01:07:10 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2008-07-31 01:07:10 -0400 |
commit | 844ae01db8ad6b8e57daa9575efbe1ff167f816e (patch) | |
tree | 4c377201cbda61af3498bf53c2cea3af56936cd1 /gcc | |
parent | 636b71b99ca087d00936621b9c518b3451254a2c (diff) | |
download | gcc-844ae01db8ad6b8e57daa9575efbe1ff167f816e.zip gcc-844ae01db8ad6b8e57daa9575efbe1ff167f816e.tar.gz gcc-844ae01db8ad6b8e57daa9575efbe1ff167f816e.tar.bz2 |
re PR c++/11309 (Testsuite failures in g++.dg/expr/anew1.C (and anew2.C anew3.C anew4.c))
PR c++/11309
* tree.c (build_aggr_init_expr): Split out...
(build_cplus_new): ...from here.
(stabilize_init): Don't mess with AGGR_INIT_EXPR either.
* init.c (build_new_1): new T() means value-initialization,
not default-initialization.
(build_vec_init): Likewise.
(build_value_init_1): Use build_aggr_init_expr.
From-SVN: r138355
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/init.c | 64 | ||||
-rw-r--r-- | gcc/cp/tree.c | 45 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/anew4.C | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/value3.C | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/new1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C | 2 |
9 files changed, 117 insertions, 46 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e98283a..f01593d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2008-07-31 Jason Merrill <jason@redhat.com> + + PR c++/11309 + * tree.c (build_aggr_init_expr): Split out... + (build_cplus_new): ...from here. + (stabilize_init): Don't mess with AGGR_INIT_EXPR either. + * init.c (build_new_1): new T() means value-initialization, + not default-initialization. + (build_vec_init): Likewise. + (build_value_init_1): Use build_aggr_init_expr. + 2008-07-30 Dodji Seketeli <dseketel@redhat.com> PR c++/36767 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f9a2af8..02d358a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4742,6 +4742,7 @@ extern tree build_min_nt (enum tree_code, ...); extern tree build_min_non_dep (enum tree_code, tree, ...); extern tree build_min_non_dep_call_list (tree, tree, tree); extern tree build_cplus_new (tree, tree); +extern tree build_aggr_init_expr (tree, tree); extern tree get_target_expr (tree); extern tree build_cplus_array_type (tree, tree); extern tree build_array_of_n_type (tree, int); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 3deb85d..5535033 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -347,7 +347,7 @@ build_value_init_1 (tree type, bool have_ctor) if (CLASS_TYPE_P (type)) { if (type_has_user_provided_constructor (type) && !have_ctor) - return build_cplus_new + return build_aggr_init_expr (type, build_special_member_call (NULL_TREE, complete_ctor_identifier, NULL_TREE, type, LOOKUP_NORMAL, @@ -511,7 +511,7 @@ perform_member_init (tree member, tree init) { /* Initialization of one array from another. */ finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init), - /*explicit_default_init_p=*/false, + /*explicit_value_init_p=*/false, /* from_array=*/1, tf_warning_or_error)); } @@ -1286,7 +1286,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED) itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); stmt_expr = build_vec_init (exp, NULL_TREE, init, - /*explicit_default_init_p=*/false, + /*explicit_value_init_p=*/false, itype && same_type_p (itype, TREE_TYPE (exp)), complain); @@ -2154,19 +2154,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, if (is_initialized) { bool stable; + bool explicit_value_init_p = false; init_expr = cp_build_indirect_ref (data_addr, NULL, complain); - if (array_p) + if (init == void_zero_node) { - bool explicit_default_init_p = false; + init = NULL_TREE; + explicit_value_init_p = true; + } - if (init == void_zero_node) - { - init = NULL_TREE; - explicit_default_init_p = true; - } - else if (init) + if (array_p) + { + if (init) { if (complain & tf_error) permerror ("ISO C++ forbids initialization in array new"); @@ -2179,7 +2179,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, integer_one_node, complain), init, - explicit_default_init_p, + explicit_value_init_p, /*from_array=*/0, complain); @@ -2190,17 +2190,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, } else { - if (init == void_zero_node) - init = build_default_init (full_type, nelts); - - if (TYPE_NEEDS_CONSTRUCTING (type)) + if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p) { init_expr = build_special_member_call (init_expr, complete_ctor_identifier, init, elt_type, LOOKUP_NORMAL, complain); - stable = stabilize_init (init_expr, &init_preeval_expr); + } + else if (explicit_value_init_p) + { + /* Something like `new int()'. */ + init_expr = build2 (INIT_EXPR, full_type, + init_expr, build_value_init (full_type)); } else { @@ -2216,8 +2218,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init, complain); - stable = stabilize_init (init_expr, &init_preeval_expr); } + stable = stabilize_init (init_expr, &init_preeval_expr); } if (init_expr == error_mark_node) @@ -2662,8 +2664,8 @@ get_temp_regvar (tree type, tree init) INIT is the (possibly NULL) initializer. - If EXPLICIT_DEFAULT_INIT_P is true, then INIT must be NULL. All - elements in the array are default-initialized. + If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL. All + elements in the array are value-initialized. FROM_ARRAY is 0 if we should init everything with INIT (i.e., every element initialized from INIT). @@ -2674,7 +2676,7 @@ get_temp_regvar (tree type, tree init) tree build_vec_init (tree base, tree maxindex, tree init, - bool explicit_default_init_p, + bool explicit_value_init_p, int from_array, tsubst_flags_t complain) { tree rval; @@ -2704,7 +2706,7 @@ build_vec_init (tree base, tree maxindex, tree init, if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; - if (explicit_default_init_p) + if (explicit_value_init_p) gcc_assert (!init); inner_elt_type = strip_array_types (atype); @@ -2840,7 +2842,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_NEEDS_CONSTRUCTING (type) || explicit_default_init_p) + || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_value_init_p) && ! (host_integerp (maxindex, 0) && (num_initialized_elts == tree_low_cst (maxindex, 0) + 1)))) @@ -2889,17 +2891,17 @@ build_vec_init (tree base, tree maxindex, tree init, ("cannot initialize multi-dimensional array with initializer"); elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), 0, 0, - /*explicit_default_init_p=*/false, + explicit_value_init_p, 0, complain); } - else if (!TYPE_NEEDS_CONSTRUCTING (type)) - elt_init = (cp_build_modify_expr - (to, INIT_EXPR, - build_zero_init (type, size_one_node, - /*static_storage_p=*/false), - complain)); + else if (explicit_value_init_p) + elt_init = build2 (INIT_EXPR, type, to, + build_value_init (type)); else - elt_init = build_aggr_init (to, init, 0, complain); + { + gcc_assert (TYPE_NEEDS_CONSTRUCTING (type)); + elt_init = build_aggr_init (to, init, 0, complain); + } current_stmt_tree ()->stmts_are_full_exprs_p = 1; finish_expr_stmt (elt_init); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 50c3049..4114f86 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -339,15 +339,17 @@ build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs, } /* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its - target. TYPE is the type that this initialization should appear to - have. + target. TYPE is the type to be initialized. - Build an encapsulation of the initialization to perform - and return it so that it can be processed by language-independent - and language-specific expression expanders. */ + Build an AGGR_INIT_EXPR to represent the initialization. This function + differs from build_cplus_new in that an AGGR_INIT_EXPR can only be used + to initialize another object, whereas a TARGET_EXPR can either + initialize another object or create its own temporary object, and as a + result building up a TARGET_EXPR requires that the type's destructor be + callable. */ tree -build_cplus_new (tree type, tree init) +build_aggr_init_expr (tree type, tree init) { tree fn; tree slot; @@ -369,8 +371,6 @@ build_cplus_new (tree type, tree init) && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0))); - slot = build_local_temp (type); - /* We split the CALL_EXPR into its function and its arguments here. Then, in expand_expr, we put them back together. The reason for this is that this expression might be a default argument @@ -384,6 +384,8 @@ build_cplus_new (tree type, tree init) type, don't mess with AGGR_INIT_EXPR. */ if (is_ctor || TREE_ADDRESSABLE (type)) { + slot = build_local_temp (type); + if (TREE_CODE(init) == CALL_EXPR) rval = build_aggr_init_array (void_type_node, fn, slot, call_expr_nargs (init), @@ -398,6 +400,30 @@ build_cplus_new (tree type, tree init) else rval = init; + return rval; +} + +/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its + target. TYPE is the type that this initialization should appear to + have. + + Build an encapsulation of the initialization to perform + and return it so that it can be processed by language-independent + and language-specific expression expanders. */ + +tree +build_cplus_new (tree type, tree init) +{ + tree rval = build_aggr_init_expr (type, init); + tree slot; + + if (TREE_CODE (rval) == AGGR_INIT_EXPR) + slot = AGGR_INIT_EXPR_SLOT (rval); + else if (TREE_CODE (rval) == CALL_EXPR) + slot = build_local_temp (type); + else + return rval; + rval = build_target_expr (slot, rval); TARGET_EXPR_IMPLICIT_P (rval) = 1; @@ -2687,7 +2713,8 @@ stabilize_init (tree init, tree *initp) return true; if (TREE_CODE (t) == INIT_EXPR - && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR) + && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR + && TREE_CODE (TREE_OPERAND (t, 1)) != AGGR_INIT_EXPR) { TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp); return true; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ba1d028..feb6b5f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6114,7 +6114,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE ? 1 + (modifycode != INIT_EXPR): 0; return build_vec_init (lhs, NULL_TREE, newrhs, - /*explicit_default_init_p=*/false, + /*explicit_value_init_p=*/false, from_array, complain); } diff --git a/gcc/testsuite/g++.dg/expr/anew4.C b/gcc/testsuite/g++.dg/expr/anew4.C index d86d525..4ce1d88 100644 --- a/gcc/testsuite/g++.dg/expr/anew4.C +++ b/gcc/testsuite/g++.dg/expr/anew4.C @@ -1,5 +1,4 @@ -// { dg-do run { xfail *-*-* } } -// XFAILed until PR2123 is fixed +// { dg-do run } // PR 11228: array operator new, with zero-initialization and a variable sized array. // Regression test for PR // Author: Matt Austern <austern@apple.com> diff --git a/gcc/testsuite/g++.dg/init/value3.C b/gcc/testsuite/g++.dg/init/value3.C new file mode 100644 index 0000000..487baab --- /dev/null +++ b/gcc/testsuite/g++.dg/init/value3.C @@ -0,0 +1,31 @@ +// Testcase for value-initialization in new-expressions. +// { dg-do run } + +#include <stdlib.h> +#include <string.h> + +// Make sure that we return memory that isn't already set to 0. +void *operator new(size_t s) +{ + void *p = malloc (s); + memset (p, 42, s); + return p; +} + +struct A { A() {} ~A() {} }; +struct B { A a; int i; }; + +int main() +{ + B *p = new B(); + if (p->i != 0) + abort(); + + p = new B[2](); + if (p[0].i != 0 || p[1].i != 0) + abort(); + + B(*p2)[2] = new B[2][2](); + if (p2[0][0].i != 0 || p2[0][1].i != 0) + abort(); +} diff --git a/gcc/testsuite/g++.dg/lookup/new1.C b/gcc/testsuite/g++.dg/lookup/new1.C index b9d0bef..ae11213 100644 --- a/gcc/testsuite/g++.dg/lookup/new1.C +++ b/gcc/testsuite/g++.dg/lookup/new1.C @@ -4,10 +4,10 @@ int main() { int i; - void* operator new(unsigned s, int* p); + void* operator new(__SIZE_TYPE__ s, int* p); int* e = new(&i) int; // { dg-error "no matching function" } int* f = new int; return 0; } -// { dg-excess-errors "operator new" } +// { dg-error "candidate" "" { target *-*-* } 0 } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C index 0fd6027..d2edb19 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C @@ -20,5 +20,5 @@ double foo (void) return v.a[2]; } -/* { dg-final { scan-tree-dump "Replaced .*iftmp.* != 0B. with .1" "forwprop1" } } */ +/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ |