From 8a1b7b7fd75a38474a335a98ac97d674b4c38b20 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 8 Jul 2016 16:23:40 -0400 Subject: [PATCH] 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 From-SVN: r238175 --- gcc/ChangeLog | 7 +++++++ gcc/gimplify.c | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9897bfce656..105d110a55f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-06-25 Jason Merrill + Richard Biener + + 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 PR target/71297 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 47c4d253e41..393bcc12208 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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 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)