tree.c (build_vec_init_expr): Split out from...
* tree.c (build_vec_init_expr): Split out from... (build_array_copy): ...here. * init.c (perform_member_init): Use it. * cp-tree.h: Declare it. * cp-gimplify.c (cp_gimplify_init_expr): Don't gimplify the slot for VEC_INIT_EXPR and AGGR_INIT_EXPR here. Drop pre/post parameters. (cp_gimplify_expr): Handle array default-initialization via VEC_INIT_EXPR. From-SVN: r165976
This commit is contained in:
parent
73c982bc87
commit
534ecb1751
@ -1,5 +1,14 @@
|
||||
2010-10-26 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* tree.c (build_vec_init_expr): Split out from...
|
||||
(build_array_copy): ...here.
|
||||
* init.c (perform_member_init): Use it.
|
||||
* cp-tree.h: Declare it.
|
||||
* cp-gimplify.c (cp_gimplify_init_expr): Don't gimplify the slot for
|
||||
VEC_INIT_EXPR and AGGR_INIT_EXPR here. Drop pre/post parameters.
|
||||
(cp_gimplify_expr): Handle array default-initialization via
|
||||
VEC_INIT_EXPR.
|
||||
|
||||
* pt.c (lookup_template_class): push_tinst_level around call to
|
||||
coerce_template_parms.
|
||||
|
||||
|
@ -424,7 +424,7 @@ gimplify_expr_stmt (tree *stmt_p)
|
||||
/* Gimplify initialization from an AGGR_INIT_EXPR. */
|
||||
|
||||
static void
|
||||
cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
|
||||
cp_gimplify_init_expr (tree *expr_p)
|
||||
{
|
||||
tree from = TREE_OPERAND (*expr_p, 1);
|
||||
tree to = TREE_OPERAND (*expr_p, 0);
|
||||
@ -451,7 +451,6 @@ cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
|
||||
if (TREE_CODE (sub) == AGGR_INIT_EXPR
|
||||
|| TREE_CODE (sub) == VEC_INIT_EXPR)
|
||||
{
|
||||
gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
|
||||
if (TREE_CODE (sub) == AGGR_INIT_EXPR)
|
||||
AGGR_INIT_EXPR_SLOT (sub) = to;
|
||||
else
|
||||
@ -531,10 +530,13 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
|
||||
case VEC_INIT_EXPR:
|
||||
{
|
||||
location_t loc = input_location;
|
||||
tree init = VEC_INIT_EXPR_INIT (*expr_p);
|
||||
int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
|
||||
gcc_assert (EXPR_HAS_LOCATION (*expr_p));
|
||||
input_location = EXPR_LOCATION (*expr_p);
|
||||
*expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
|
||||
VEC_INIT_EXPR_INIT (*expr_p), false, 1,
|
||||
init, /*explicit_value_init_p*/false,
|
||||
from_array,
|
||||
tf_warning_or_error);
|
||||
ret = GS_OK;
|
||||
input_location = loc;
|
||||
@ -556,7 +558,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
|
||||
LHS of an assignment might also be involved in the RHS, as in bug
|
||||
25979. */
|
||||
case INIT_EXPR:
|
||||
cp_gimplify_init_expr (expr_p, pre_p, post_p);
|
||||
cp_gimplify_init_expr (expr_p);
|
||||
if (TREE_CODE (*expr_p) != INIT_EXPR)
|
||||
return GS_OK;
|
||||
/* Otherwise fall through. */
|
||||
|
@ -5377,6 +5377,7 @@ extern tree get_target_expr (tree);
|
||||
extern tree build_cplus_array_type (tree, tree);
|
||||
extern tree build_array_of_n_type (tree, int);
|
||||
extern tree build_array_copy (tree);
|
||||
extern tree build_vec_init_expr (tree, tree);
|
||||
extern tree hash_tree_cons (tree, tree, tree);
|
||||
extern tree hash_tree_chain (tree, tree);
|
||||
extern tree build_qualified_name (tree, tree, tree, bool);
|
||||
|
@ -486,16 +486,23 @@ perform_member_init (tree member, tree init)
|
||||
}
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
{
|
||||
if (init != NULL_TREE
|
||||
&& TREE_CODE (type) == ARRAY_TYPE
|
||||
&& TREE_CHAIN (init) == NULL_TREE
|
||||
&& TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
/* Initialization of one array from another. */
|
||||
finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
|
||||
/*explicit_value_init_p=*/false,
|
||||
/* from_array=*/1,
|
||||
tf_warning_or_error));
|
||||
if (init)
|
||||
{
|
||||
gcc_assert (TREE_CHAIN (init) == NULL_TREE);
|
||||
init = TREE_VALUE (init);
|
||||
}
|
||||
if (init == NULL_TREE
|
||||
|| same_type_ignoring_top_level_qualifiers_p (type,
|
||||
TREE_TYPE (init)))
|
||||
{
|
||||
init = build_vec_init_expr (type, init);
|
||||
init = build2 (INIT_EXPR, type, decl, init);
|
||||
finish_expr_stmt (init);
|
||||
}
|
||||
else
|
||||
error ("invalid initializer for array member %q#D", member);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -452,14 +452,41 @@ build_cplus_new (tree type, tree init)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Return a TARGET_EXPR which expresses the direct-initialization of one
|
||||
array from another. */
|
||||
/* Return a TARGET_EXPR which expresses the initialization of an array to
|
||||
be named later, either default-initialization or copy-initialization
|
||||
from another array of the same type. */
|
||||
|
||||
tree
|
||||
build_array_copy (tree init)
|
||||
build_vec_init_expr (tree type, tree init)
|
||||
{
|
||||
tree type = TREE_TYPE (init);
|
||||
tree slot = build_local_temp (type);
|
||||
tree slot;
|
||||
tree inner_type = strip_array_types (type);
|
||||
|
||||
gcc_assert (init == NULL_TREE
|
||||
|| (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (init))));
|
||||
|
||||
/* Since we're deferring building the actual constructor calls until
|
||||
gimplification time, we need to build one now and throw it away so
|
||||
that the relevant constructor gets mark_used before cgraph decides
|
||||
what functions are needed. Here we assume that init is either
|
||||
NULL_TREE or another array to copy. */
|
||||
if (CLASS_TYPE_P (inner_type))
|
||||
{
|
||||
VEC(tree,gc) *argvec = make_tree_vector ();
|
||||
if (init)
|
||||
{
|
||||
tree dummy = build_dummy_object (inner_type);
|
||||
if (!real_lvalue_p (init))
|
||||
dummy = move (dummy);
|
||||
VEC_quick_push (tree, argvec, dummy);
|
||||
}
|
||||
build_special_member_call (NULL_TREE, complete_ctor_identifier,
|
||||
&argvec, inner_type, LOOKUP_NORMAL,
|
||||
tf_warning_or_error);
|
||||
}
|
||||
|
||||
slot = build_local_temp (type);
|
||||
init = build2 (VEC_INIT_EXPR, type, slot, init);
|
||||
SET_EXPR_LOCATION (init, input_location);
|
||||
init = build_target_expr (slot, init);
|
||||
@ -468,6 +495,12 @@ build_array_copy (tree init)
|
||||
return init;
|
||||
}
|
||||
|
||||
tree
|
||||
build_array_copy (tree init)
|
||||
{
|
||||
return build_vec_init_expr (TREE_TYPE (init), init);
|
||||
}
|
||||
|
||||
/* Build a TARGET_EXPR using INIT to initialize a new temporary of the
|
||||
indicated TYPE. */
|
||||
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
b();
|
||||
};
|
||||
|
||||
b::b() : three(this) // { dg-error "bad array initializer" }
|
||||
b::b() : three(this) // { dg-error "array" }
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,6 @@ class B
|
||||
};
|
||||
|
||||
B::B (const A a[])
|
||||
: ary(a) // { dg-error "bad array initializer" }
|
||||
: ary(a) // { dg-error "array" }
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user