diff options
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 122 |
1 files changed, 86 insertions, 36 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 9383e928fa5..8a8dc782ca3 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; @@ -1570,12 +1572,25 @@ integral_constant_value (tree decl) /* And so are variables with a 'const' type -- unless they are also 'volatile'. */ && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)) - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))) - && DECL_INITIAL (decl) - && DECL_INITIAL (decl) != error_mark_node - && TREE_TYPE (DECL_INITIAL (decl)) - && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (DECL_INITIAL (decl)))) - decl = DECL_INITIAL (decl); + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)))) + { + tree init; + /* If DECL is a static data member in a template class, we must + instantiate it here. The initializer for the static data + member is not processed until needed; we need it now. */ + mark_used (decl); + init = DECL_INITIAL (decl); + /* If we are currently processing a template, the + initializer for a static data member may not be dependent, + but it is not folded until instantiation time. */ + if (init) + init = fold_non_dependent_expr (init); + if (!(init || init == error_mark_node) + || !TREE_TYPE (init) + || !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init))) + break; + decl = init; + } return decl; } @@ -1918,6 +1933,11 @@ build_new_1 (tree exp) args = tree_cons (NULL_TREE, size, placement); /* Do name-lookup to find the appropriate operator. */ fns = lookup_fnfields (elt_type, fnname, /*protect=*/2); + if (fns == NULL_TREE) + { + error ("no suitable %qD found in class %qT", fnname, elt_type); + return error_mark_node; + } if (TREE_CODE (fns) == TREE_LIST) { error ("request for member %qD is ambiguous", fnname); @@ -2050,46 +2070,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) @@ -2370,8 +2403,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 @@ -2380,7 +2417,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; @@ -2409,6 +2448,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 @@ -2539,7 +2581,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)))) @@ -2548,6 +2590,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); @@ -2557,9 +2600,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) @@ -2582,11 +2626,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); |