Commit 8a1b7b7f by Jason Merrill Committed by Jason Merrill

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
parent 642bcbdf
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> 2016-07-08 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR target/71297 PR target/71297
......
...@@ -3813,6 +3813,18 @@ rhs_predicate_for (tree lhs) ...@@ -3813,6 +3813,18 @@ rhs_predicate_for (tree lhs)
return is_gimple_mem_rhs_or_call; 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 /* Gimplify a C99 compound literal expression. This just means adding
the DECL_EXPR before the current statement and using its anonymous the DECL_EXPR before the current statement and using its anonymous
decl instead. */ decl instead. */
...@@ -4778,10 +4790,6 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ...@@ -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. */ that is what we must do here. */
maybe_with_size_expr (from_p); 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 /* 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 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
a toplevel statement, when gimplifying the GENERIC expression 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, ...@@ -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 reaches the CALL_EXPR. On return from gimplify_expr, the newly
created GIMPLE_CALL <foo> will be the last statement in *PRE_P 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. */ 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) if (ret == GS_ERROR)
return ret; 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 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
size as argument to the call. */ size as argument to the call. */
if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment