diff options
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 104 |
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); |