This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Semantics of MODIFY_EXPR with CONSTRUCTOR rhs
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: rth at redhat dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 2 Aug 04 18:58:26 EDT
- Subject: Re: Semantics of MODIFY_EXPR with CONSTRUCTOR rhs
OK, this version of the function passes that test and doesn't cause
any more to fail:
/* A subroutine of gimplify_init_constructor. Pre-evaluate *EXPR_P,
force values that overlap with the lhs (as described by *DATA)
into temporaries. */
static void
gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
struct gimplify_init_ctor_preeval_data *data)
{
enum gimplify_status one;
/* If the value is invariant, then there's nothing to pre-evaluate.
But ensure it doesn't have any side-effects since a SAVE_EXPR is
invariant but has side effects and might contain a reference to
the object we're initializing. */
if (TREE_INVARIANT (*expr_p) && !TREE_SIDE_EFFECTS (*expr_p))
return;
/* Recurse for nested constructors. */
if (TREE_CODE (*expr_p) == CONSTRUCTOR)
{
tree list;
for (list = CONSTRUCTOR_ELTS (*expr_p); list ; list = TREE_CHAIN (list))
gimplify_init_ctor_preeval (&TREE_VALUE (list), pre_p, post_p, data);
return;
}
/* We can't preevaluate if the type contains a placeholder. */
if (type_contains_placeholder_p (TREE_TYPE (*expr_p)))
return;
/* Gimplify the constructor element to something appropriate for the rhs
of a MODIFY_EXPR. Given that we know the lhs is an aggregate, we know
the gimplifier will consider this a store to memory. Doing this
gimplification now means that we won't have to deal with complicated
language-specific trees, nor trees like SAVE_EXPR that can induce
exponential search behaviour. */
one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
if (one == GS_ERROR)
{
*expr_p = NULL;
return;
}
/* If we gimplified to a bare decl, we can be sure that it doesn't overlap
with the lhs, since "a = { .x=a }" doesn't make sense. This will be
always be true for all scalars, since is_gimple_mem_rhs insists on a
temporary variable for them. */
if (DECL_P (*expr_p))
return;
/* If this is of variable size, we have no choice but to assume it doesn't
overlap since we can't make a temporary for it. */
if (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (*expr_p))))
return;
/* Otherwise, we must search for overlap ... */
if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
return;
/* ... and if found, force the value into a temporary. */
*expr_p = get_formal_tmp_var (*expr_p, pre_p);
}