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.c122
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);