summaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-08-26 19:32:31 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-08-26 19:32:31 +0000
commit687a1c50251b0c5cb404e53bbc87b9683563ed8e (patch)
treeedd60898da146e452d1ebf12a4a3cf3feccf5878 /gcc/cp/init.c
parente6be4aaafac14a477aa86cc3eaed48752c33dfec (diff)
downloadgcc-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.c92
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);