aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c104
1 files changed, 55 insertions, 49 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3deb85d432b..c6d63b84096 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);
@@ -2055,11 +2055,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return rval;
}
- /* While we're working, use a pointer to the type we've actually
- allocated. Store the result of the call in a variable so that we
- can use it more than once. */
- full_pointer_type = build_pointer_type (full_type);
- alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
+ /* Store the result of the allocation call in a variable so that we can
+ use it more than once. */
+ alloc_expr = get_target_expr (alloc_call);
alloc_node = TARGET_EXPR_SLOT (alloc_expr);
/* Strip any COMPOUND_EXPRs from ALLOC_CALL. */
@@ -2111,16 +2109,17 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
tree size_ptr_type;
/* Adjust so we're pointing to the start of the object. */
- data_addr = get_target_expr (build2 (POINTER_PLUS_EXPR, full_pointer_type,
- alloc_node, cookie_size));
+ data_addr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
+ alloc_node, cookie_size);
/* Store the number of bytes allocated so that we can know how
many elements to destroy later. We use the last sizeof
(size_t) bytes to store the number of elements. */
- cookie_ptr = fold_build1 (NEGATE_EXPR, sizetype, size_in_bytes (sizetype));
+ cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
+ cookie_ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
+ alloc_node, cookie_ptr);
size_ptr_type = build_pointer_type (sizetype);
- cookie_ptr = build2 (POINTER_PLUS_EXPR, size_ptr_type,
- fold_convert (size_ptr_type, data_addr), cookie_ptr);
+ cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
@@ -2134,11 +2133,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
cookie = build2 (MODIFY_EXPR, sizetype, cookie,
- size_in_bytes(elt_type));
+ size_in_bytes (elt_type));
cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
cookie, cookie_expr);
}
- data_addr = TARGET_EXPR_SLOT (data_addr);
}
else
{
@@ -2146,6 +2144,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
data_addr = alloc_node;
}
+ /* Now use a pointer to the type we've actually allocated. */
+ full_pointer_type = build_pointer_type (full_type);
+ data_addr = fold_convert (full_pointer_type, data_addr);
+
/* Now initialize the allocated object. Note that we preevaluate the
initialization expression, apart from the actual constructor call or
assignment--we do this because we want to delay the allocation as long
@@ -2154,19 +2156,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 +2181,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 +2192,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 +2220,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)
@@ -2239,11 +2243,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
/* The Standard is unclear here, but the right thing to do
is to use the same method for finding deallocation
functions that we use for finding allocation functions. */
- cleanup = build_op_delete_call (dcode, alloc_node, size,
- globally_qualified_p,
- (placement_allocation_fn_p
- ? alloc_call : NULL_TREE),
- alloc_fn);
+ cleanup = (build_op_delete_call
+ (dcode,
+ fold_convert (full_pointer_type, alloc_node),
+ size,
+ globally_qualified_p,
+ placement_allocation_fn_p ? alloc_call : NULL_TREE,
+ alloc_fn));
if (!cleanup)
/* We're done. */;
@@ -2298,7 +2304,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (cookie_expr)
rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
- if (rval == alloc_node)
+ if (rval == data_addr)
/* If we don't have an initializer or a cookie, strip the TARGET_EXPR
and return the call (which doesn't need to be adjusted). */
rval = TARGET_EXPR_INITIAL (alloc_expr);
@@ -2662,8 +2668,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 +2680,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 +2710,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 +2846,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 +2895,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);