diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-26 19:32:31 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-26 19:32:31 +0000 |
commit | 687a1c50251b0c5cb404e53bbc87b9683563ed8e (patch) | |
tree | edd60898da146e452d1ebf12a4a3cf3feccf5878 /gcc/cp/init.c | |
parent | e6be4aaafac14a477aa86cc3eaed48752c33dfec (diff) | |
download | gcc-687a1c50251b0c5cb404e53bbc87b9683563ed8e.tar.gz |
PR c++/23491
* cp-tree.h (build_vec_init): Adjust prototype.
* init.c (perform_member_init): Adjust call to build_vec_init.
(build_aggr_init): Likewise.
(build_new_1): Do not call build_default_init for array types.
(build_vec_init): Add explicit_default_init_p parameter. Perform
default initialization of vector elements when set.
* typeck.c (build_modify_expr): Adjust call to build_vec_init.
PR c++/23491
* g++.dg/init/new14.C: New test.
* g++.dg/expr/anew1.C: Do not XFAIL.
* g++.dg/expr/anew2.C: Likewise.
* g++.dg/expr/anew3.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103530 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 92 |
1 files changed, 62 insertions, 30 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index a2fcc1ffe60..690e35f8913 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -358,6 +358,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, /* from_array=*/1)); } else @@ -1112,6 +1113,7 @@ build_aggr_init (tree exp, tree init, int flags) 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, itype && same_type_p (itype, TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; @@ -2055,46 +2057,59 @@ build_new_1 (tree exp) init_expr = build_indirect_ref (data_addr, NULL); - if (init == void_zero_node) - init = build_default_init (full_type, nelts); - else if (init && array_p) - pedwarn ("ISO C++ forbids initialization in array new"); - if (array_p) { + bool explicit_default_init_p = false; + + if (init == void_zero_node) + { + init = NULL_TREE; + explicit_default_init_p = true; + } + else if (init) + pedwarn ("ISO C++ forbids initialization in array new"); + init_expr = build_vec_init (init_expr, cp_build_binary_op (MINUS_EXPR, outer_nelts, integer_one_node), - init, /*from_array=*/0); + init, + explicit_default_init_p, + /*from_array=*/0); /* An array initialization is stable because the initialization of each element is a full-expression, so the temporaries don't leak out. */ stable = true; } - else if (TYPE_NEEDS_CONSTRUCTING (type)) - { - init_expr = build_special_member_call (init_expr, - complete_ctor_identifier, - init, elt_type, - LOOKUP_NORMAL); - stable = stabilize_init (init_expr, &init_preeval_expr); - } else { - /* We are processing something like `new int (10)', which - means allocate an int, and initialize it with 10. */ - - if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, "new initializer"); + if (init == void_zero_node) + init = build_default_init (full_type, nelts); + if (TYPE_NEEDS_CONSTRUCTING (type)) + { + init_expr = build_special_member_call (init_expr, + complete_ctor_identifier, + init, elt_type, + LOOKUP_NORMAL); + stable = stabilize_init (init_expr, &init_preeval_expr); + } else - gcc_assert (TREE_CODE (init) != CONSTRUCTOR - || TREE_TYPE (init) != NULL_TREE); - - init_expr = build_modify_expr (init_expr, INIT_EXPR, init); - stable = stabilize_init (init_expr, &init_preeval_expr); + { + /* We are processing something like `new int (10)', which + means allocate an int, and initialize it with 10. */ + + if (TREE_CODE (init) == TREE_LIST) + init = build_x_compound_expr_from_list (init, + "new initializer"); + else + gcc_assert (TREE_CODE (init) != CONSTRUCTOR + || TREE_TYPE (init) != NULL_TREE); + + init_expr = build_modify_expr (init_expr, INIT_EXPR, init); + stable = stabilize_init (init_expr, &init_preeval_expr); + } } if (init_expr == error_mark_node) @@ -2375,8 +2390,12 @@ get_temp_regvar (tree type, tree init) MAXINDEX is the maximum index of the array (one less than the number of elements). It is only used if TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE. + 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. + FROM_ARRAY is 0 if we should init everything with INIT (i.e., every element initialized from INIT). FROM_ARRAY is 1 if we should index into INIT in parallel @@ -2385,7 +2404,9 @@ get_temp_regvar (tree type, tree init) but use assignment instead of initialization. */ tree -build_vec_init (tree base, tree maxindex, tree init, int from_array) +build_vec_init (tree base, tree maxindex, tree init, + bool explicit_default_init_p, + int from_array) { tree rval; tree base2 = NULL_TREE; @@ -2414,6 +2435,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; + if (explicit_default_init_p) + gcc_assert (!init); + inner_elt_type = strip_array_types (atype); if (init && (from_array == 2 @@ -2544,7 +2568,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) We do need to keep going if we're copying an array. */ if (from_array - || (TYPE_NEEDS_CONSTRUCTING (type) + || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p) && ! (host_integerp (maxindex, 0) && (num_initialized_elts == tree_low_cst (maxindex, 0) + 1)))) @@ -2553,6 +2577,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) we've already initialized all the elements. */ tree for_stmt; tree elt_init; + tree to; for_stmt = begin_for_stmt (); finish_for_init_stmt (for_stmt); @@ -2562,9 +2587,10 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) finish_for_expr (build_unary_op (PREDECREMENT_EXPR, iterator, 0), for_stmt); + to = build1 (INDIRECT_REF, type, base); + if (from_array) { - tree to = build1 (INDIRECT_REF, type, base); tree from; if (base2) @@ -2587,11 +2613,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) sorry ("cannot initialize multi-dimensional array with initializer"); elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), - 0, 0, 0); + 0, 0, + /*explicit_default_init_p=*/false, + 0); } + else if (!TYPE_NEEDS_CONSTRUCTING (type)) + elt_init = (build_modify_expr + (to, INIT_EXPR, + build_zero_init (type, size_one_node, + /*static_storage_p=*/false))); else - elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), - init, 0); + elt_init = build_aggr_init (to, init, 0); current_stmt_tree ()->stmts_are_full_exprs_p = 1; finish_expr_stmt (elt_init); |