This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] PATCH for c++/11266
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Nov 2003 11:19:15 -0500
- Subject: [tree-ssa] PATCH for c++/11266
The expander is careful to only expand a TARGET_EXPR the first time around;
later expansions just return the rtl for the slot. This patch changes the
gimplifier to work similarly.
Of course, we shouldn't be see the same TARGET_EXPR in multiple places in
the testcase in the PR, but that's another bug which can be addressed
separately.
Tested athlon-pc-linux-gnu, applied to tree-ssa. Test in
g++.dg/init/placement1.C.
2003-11-17 Jason Merrill <jason@redhat.com>
PR c++/11266
* gimplify.c (gimple_add_tmp_var): Also make sure
seen_in_bind_expr isn't set.
(mostly_copy_tree_r): Don't copy a TARGET_EXPR.
(gimplify_target_expr): Only expand a TARGET_EXPR the first time
we see it.
*** gimplify.c.~1~ 2003-11-15 16:30:50.000000000 -0500
--- gimplify.c 2003-11-17 11:14:46.000000000 -0500
*************** declare_tmp_vars (tree vars, tree scope)
*** 520,526 ****
void
gimple_add_tmp_var (tree tmp)
{
! if (TREE_CHAIN (tmp))
abort ();
DECL_CONTEXT (tmp) = current_function_decl;
--- 520,526 ----
void
gimple_add_tmp_var (tree tmp)
{
! if (TREE_CHAIN (tmp) || tmp->decl.seen_in_bind_expr)
abort ();
DECL_CONTEXT (tmp) = current_function_decl;
*************** annotate_all_with_locus (tree *stmt_p, l
*** 582,591 ****
}
}
! /* Similar to copy_tree_r() but do not copy SAVE_EXPR nodes. These nodes
! model computations that should only be done once. If we were to unshare
! something like SAVE_EXPR(i++), the gimplification process would create
! wrong code. */
static tree
mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
--- 582,591 ----
}
}
! /* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
! These nodes model computations that should only be done once. If we
! were to unshare something like SAVE_EXPR(i++), the gimplification
! process would create wrong code. */
static tree
mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
*************** mostly_copy_tree_r (tree *tp, int *walk_
*** 594,600 ****
/* Don't unshare types, constants and SAVE_EXPR nodes. */
if (TREE_CODE_CLASS (code) == 't'
|| TREE_CODE_CLASS (code) == 'c'
! || code == SAVE_EXPR
/* We can't do anything sensible with a BLOCK used as an expression,
but we also can't abort when we see it because of non-expression
uses. So just avert our eyes and cross our fingers. Silly Java. */
--- 594,600 ----
/* Don't unshare types, constants and SAVE_EXPR nodes. */
if (TREE_CODE_CLASS (code) == 't'
|| TREE_CODE_CLASS (code) == 'c'
! || code == SAVE_EXPR || code == TARGET_EXPR
/* We can't do anything sensible with a BLOCK used as an expression,
but we also can't abort when we see it because of non-expression
uses. So just avert our eyes and cross our fingers. Silly Java. */
*************** gimplify_target_expr (tree *expr_p, tree
*** 2672,2695 ****
tree init = TARGET_EXPR_INITIAL (targ);
enum gimplify_status ret;
! /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the
! temps list. */
! gimple_add_tmp_var (temp);
!
! /* Build up the initialization and add it to pre_p. */
! init = build (MODIFY_EXPR, void_type_node, temp, init);
! ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
! if (ret == GS_ERROR)
! return GS_ERROR;
! append_to_statement_list (init, pre_p);
! /* If needed, push the cleanup for the temp. */
! if (TARGET_EXPR_CLEANUP (targ))
! {
! gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
! gimple_push_cleanup (TARGET_EXPR_CLEANUP (targ), pre_p);
}
*expr_p = temp;
return GS_OK;
--- 2672,2705 ----
tree init = TARGET_EXPR_INITIAL (targ);
enum gimplify_status ret;
! if (init)
! {
! /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the
! temps list. */
! gimple_add_tmp_var (temp);
!
! /* Build up the initialization and add it to pre_p. */
! init = build (MODIFY_EXPR, void_type_node, temp, init);
! ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
! if (ret == GS_ERROR)
! return GS_ERROR;
! append_to_statement_list (init, pre_p);
! /* If needed, push the cleanup for the temp. */
! if (TARGET_EXPR_CLEANUP (targ))
! {
! gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
! gimple_push_cleanup (TARGET_EXPR_CLEANUP (targ), pre_p);
! }
!
! /* Only expand this once. */
! TREE_OPERAND (targ, 3) = init;
! TARGET_EXPR_INITIAL (targ) = NULL_TREE;
}
+ else if (!temp->decl.seen_in_bind_expr)
+ /* We should have expanded this before. */
+ abort ();
*expr_p = temp;
return GS_OK;