X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Finit.c;h=bb0e618fbeef26baf5360b30d82388a4692e7a80;hb=f4a24f32103062b2f0906eb10c91ec98b61bdd2e;hp=8e28e3b3044bd4fb604912b73cffe2882ab307ed;hpb=648ae09f368b82c06f5ab0d08b8d847cbe4bd785;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8e28e3b3044..bb0e618fbee 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -140,7 +140,9 @@ initialize_vtbl_ptrs (tree addr) zero-initialization does not simply mean filling the storage with zero bytes. FIELD_SIZE, if non-NULL, is the bit size of the field, subfields with bit positions at or above that bit size shouldn't - be added. */ + be added. Note that this only works when the result is assigned + to a base COMPONENT_REF; if we only have a pointer to the base subobject, + expand_assignment will end up clearing the full size of TYPE. */ static tree build_zero_init_1 (tree type, tree nelts, bool static_storage_p, @@ -180,7 +182,7 @@ build_zero_init_1 (tree type, tree nelts, bool static_storage_p, init = convert (type, nullptr_node); else if (SCALAR_TYPE_P (type)) init = convert (type, integer_zero_node); - else if (CLASS_TYPE_P (type)) + else if (RECORD_OR_UNION_CODE_P (TREE_CODE (type))) { tree field; VEC(constructor_elt,gc) *v = NULL; @@ -252,21 +254,23 @@ build_zero_init_1 (tree type, tree nelts, bool static_storage_p, have an upper bound of -1. */ if (!tree_int_cst_equal (max_index, integer_minus_one_node)) { - constructor_elt *ce; - - v = VEC_alloc (constructor_elt, gc, 1); - ce = VEC_quick_push (constructor_elt, v, NULL); + constructor_elt ce; /* If this is a one element array, we just use a regular init. */ if (tree_int_cst_equal (size_zero_node, max_index)) - ce->index = size_zero_node; + ce.index = size_zero_node; else - ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node, - max_index); + ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node, + max_index); - ce->value = build_zero_init_1 (TREE_TYPE (type), - /*nelts=*/NULL_TREE, - static_storage_p, NULL_TREE); + ce.value = build_zero_init_1 (TREE_TYPE (type), + /*nelts=*/NULL_TREE, + static_storage_p, NULL_TREE); + if (ce.value) + { + v = VEC_alloc (constructor_elt, gc, 1); + *VEC_quick_push (constructor_elt, v, NULL) = ce; + } } /* Build a constructor to contain the initializations. */ @@ -333,7 +337,8 @@ build_value_init (tree type, tsubst_flags_t complain) constructor. */ /* The AGGR_INIT_EXPR tweaking below breaks in templates. */ - gcc_assert (!processing_template_decl || SCALAR_TYPE_P (type)); + gcc_assert (!processing_template_decl + || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)); if (CLASS_TYPE_P (type)) { @@ -359,11 +364,9 @@ build_value_init (tree type, tsubst_flags_t complain) tree ctor = build_special_member_call (NULL_TREE, complete_ctor_identifier, NULL, type, LOOKUP_NORMAL, complain); + ctor = build_aggr_init_expr (type, ctor, complain); if (ctor != error_mark_node) - { - ctor = build_aggr_init_expr (type, ctor, complain); - AGGR_INIT_ZERO_FIRST (ctor) = 1; - } + AGGR_INIT_ZERO_FIRST (ctor) = 1; return ctor; } } @@ -376,6 +379,12 @@ build_value_init (tree type, tsubst_flags_t complain) tree build_value_init_noctor (tree type, tsubst_flags_t complain) { + if (!COMPLETE_TYPE_P (type)) + { + if (complain & tf_error) + error ("value-initialization of incomplete type %qT", type); + return error_mark_node; + } /* FIXME the class and array cases should just use digest_init once it is SFINAE-enabled. */ if (CLASS_TYPE_P (type)) @@ -442,28 +451,31 @@ build_value_init_noctor (tree type, tsubst_flags_t complain) have an upper bound of -1. */ if (!tree_int_cst_equal (max_index, integer_minus_one_node)) { - constructor_elt *ce; - - v = VEC_alloc (constructor_elt, gc, 1); - ce = VEC_quick_push (constructor_elt, v, NULL); + constructor_elt ce; /* If this is a one element array, we just use a regular init. */ if (tree_int_cst_equal (size_zero_node, max_index)) - ce->index = size_zero_node; + ce.index = size_zero_node; else - ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node, - max_index); + ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node, + max_index); - ce->value = build_value_init (TREE_TYPE (type), complain); + ce.value = build_value_init (TREE_TYPE (type), complain); - if (ce->value == error_mark_node) - return error_mark_node; + if (ce.value) + { + if (ce.value == error_mark_node) + return error_mark_node; - /* We shouldn't have gotten here for anything that would need - non-trivial initialization, and gimplify_init_ctor_preeval - would need to be fixed to allow it. */ - gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR - && TREE_CODE (ce->value) != AGGR_INIT_EXPR); + v = VEC_alloc (constructor_elt, gc, 1); + *VEC_quick_push (constructor_elt, v, NULL) = ce; + + /* We shouldn't have gotten here for anything that would need + non-trivial initialization, and gimplify_init_ctor_preeval + would need to be fixed to allow it. */ + gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR + && TREE_CODE (ce.value) != AGGR_INIT_EXPR); + } } /* Build a constructor to contain the initializations. */ @@ -1729,8 +1741,10 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags, that's value-initialization. */ if (init == void_type_node) { - /* If no user-provided ctor, we need to zero out the object. */ - if (!type_has_user_provided_constructor (type)) + /* If the type has data but no user-provided ctor, we need to zero + out the object. */ + if (!type_has_user_provided_constructor (type) + && !is_really_empty_class (type)) { tree field_size = NULL_TREE; if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type) @@ -2761,7 +2775,9 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, if (type == error_mark_node) return error_mark_node; - if (nelts == NULL_TREE && VEC_length (tree, *init) == 1) + if (nelts == NULL_TREE && VEC_length (tree, *init) == 1 + /* Don't do auto deduction where it might affect mangling. */ + && (!processing_template_decl || at_function_scope_p ())) { tree auto_node = type_uses_auto (type); if (auto_node) @@ -2783,7 +2799,8 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, orig_placement = make_tree_vector_copy (*placement); orig_nelts = nelts; - orig_init = make_tree_vector_copy (*init); + if (*init) + orig_init = make_tree_vector_copy (*init); make_args_non_dependent (*placement); if (nelts) @@ -3139,8 +3156,7 @@ build_vec_init (tree base, tree maxindex, tree init, if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype)) maxindex = array_type_nelts (atype); - if (maxindex == NULL_TREE || maxindex == error_mark_node - || integer_all_onesp (maxindex)) + if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; if (explicit_value_init_p) @@ -3324,9 +3340,12 @@ build_vec_init (tree base, tree maxindex, tree init, else { if (do_static_init) - CONSTRUCTOR_APPEND_ELT (new_vec, field, - build_zero_init (TREE_TYPE (e), - NULL_TREE, true)); + { + tree value = build_zero_init (TREE_TYPE (e), NULL_TREE, + true); + if (value) + CONSTRUCTOR_APPEND_ELT (new_vec, field, value); + } saw_non_const = true; } } @@ -3490,7 +3509,9 @@ build_vec_init (tree base, tree maxindex, tree init, if (TREE_CODE (type) == ARRAY_TYPE) m = cp_build_binary_op (input_location, MULT_EXPR, m, - array_type_nelts_total (type), + /* Force signed arithmetic. */ + convert (TREE_TYPE (m), + array_type_nelts_total (type)), complain); finish_cleanup_try_block (try_block);