P0145: Refining Expression Order for C++ (assignment)

* gimplify.c (initial_rhs_predicate_for): New.
	(gimplfy_modify_expr): Gimplify RHS before LHS.

Co-Authored-By: Richard Biener <rguenther@suse.de>

From-SVN: r238175
This commit is contained in:
Jason Merrill 2016-07-08 16:23:40 -04:00 committed by Jason Merrill
parent 642bcbdf1d
commit 8a1b7b7fd7
2 changed files with 38 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2016-06-25 Jason Merrill <jason@redhat.com>
Richard Biener <rguenther@suse.de>
P0145: Refining Expression Order for C++.
* gimplify.c (initial_rhs_predicate_for): New.
(gimplfy_modify_expr): Gimplify RHS before LHS.
2016-07-08 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR target/71297

View File

@ -3813,6 +3813,18 @@ rhs_predicate_for (tree lhs)
return is_gimple_mem_rhs_or_call;
}
/* Return the initial guess for an appropriate RHS predicate for this LHS,
before the LHS has been gimplified. */
static gimple_predicate
initial_rhs_predicate_for (tree lhs)
{
if (is_gimple_reg_type (TREE_TYPE (lhs)))
return is_gimple_reg_rhs_or_call;
else
return is_gimple_mem_rhs_or_call;
}
/* Gimplify a C99 compound literal expression. This just means adding
the DECL_EXPR before the current statement and using its anonymous
decl instead. */
@ -4778,10 +4790,6 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
that is what we must do here. */
maybe_with_size_expr (from_p);
ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
if (ret == GS_ERROR)
return ret;
/* As a special case, we have to temporarily allow for assignments
with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
a toplevel statement, when gimplifying the GENERIC expression
@ -4794,11 +4802,28 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
reaches the CALL_EXPR. On return from gimplify_expr, the newly
created GIMPLE_CALL <foo> will be the last statement in *PRE_P
and all we need to do here is set 'a' to be its LHS. */
ret = gimplify_expr (from_p, pre_p, post_p, rhs_predicate_for (*to_p),
fb_rvalue);
/* Gimplify the RHS first for C++17 and bug 71104. */
gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
if (ret == GS_ERROR)
return ret;
/* Then gimplify the LHS. */
ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
if (ret == GS_ERROR)
return ret;
/* Now that the LHS is gimplified, re-gimplify the RHS if our initial
guess for the predicate was wrong. */
gimple_predicate final_pred = rhs_predicate_for (*to_p);
if (final_pred != initial_pred)
{
ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
if (ret == GS_ERROR)
return ret;
}
/* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
size as argument to the call. */
if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)