aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-gimplify.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-10-11 09:36:07 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-10-11 09:36:07 +0200
commit1a37b6d9a7e57c71b1bfe449ebd275eb408117fb (patch)
treefe29653bb010efc768398510adcd8af902405b71 /gcc/cp/cp-gimplify.c
parent1e99e6fe6bb61ad2011030324cfdf84d2a67e75d (diff)
downloadgcc-1a37b6d9a7e57c71b1bfe449ebd275eb408117fb.zip
gcc-1a37b6d9a7e57c71b1bfe449ebd275eb408117fb.tar.gz
gcc-1a37b6d9a7e57c71b1bfe449ebd275eb408117fb.tar.bz2
re PR c++/91987 (-fstrict-eval-order issues)
PR c++/91987 cp/ * decl2.c (grok_array_decl): For -fstrong-eval-order, when array ref operands have been swapped and at least one operand has side-effects, revert the swapping before calling build_array_ref. * typeck.c (cp_build_array_ref): For non-ARRAY_TYPE array ref with side-effects on the index operand, if -fstrong-eval-order use save_expr around the array operand. (cp_build_binary_op): For shifts with side-effects in the second operand, wrap first operand into SAVE_EXPR and evaluate it before the shift. * semantics.c (handle_omp_array_sections_1): Temporarily disable flag_strong_eval_order during OMP_CLAUSE_REDUCTION array section processing. * cp-gimplify.c (gimplify_to_rvalue): New function. (cp_gimplify_expr): Use it. testsuite/ * g++.dg/cpp1z/eval-order6.C: New test. * g++.dg/cpp1z/eval-order7.C: New test. * g++.dg/cpp1z/eval-order8.C: New test. * c-c++-common/gomp/pr91987.c: New test. From-SVN: r276860
Diffstat (limited to 'gcc/cp/cp-gimplify.c')
-rw-r--r--gcc/cp/cp-gimplify.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 6545392..154fa70 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -638,6 +638,22 @@ lvalue_has_side_effects (tree e)
return TREE_SIDE_EFFECTS (e);
}
+/* Gimplify *EXPR_P as rvalue into an expression that can't be modified
+ by expressions with side-effects in other operands. */
+
+static enum gimplify_status
+gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ bool (*gimple_test_f) (tree))
+{
+ enum gimplify_status t
+ = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
+ if (t == GS_ERROR)
+ return GS_ERROR;
+ else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL);
+ return t;
+}
+
/* Do C++-specific gimplification. Args are as for gimplify_expr. */
int
@@ -823,15 +839,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
&& cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
{
enum gimplify_status t
- = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
- is_gimple_call_addr, fb_rvalue);
+ = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
+ is_gimple_call_addr);
if (t == GS_ERROR)
ret = GS_ERROR;
- else if (is_gimple_variable (CALL_EXPR_FN (*expr_p))
- && TREE_CODE (CALL_EXPR_FN (*expr_p)) != SSA_NAME)
- CALL_EXPR_FN (*expr_p)
- = get_initialized_tmp_var (CALL_EXPR_FN (*expr_p), pre_p,
- NULL);
}
if (!CALL_EXPR_FN (*expr_p))
/* Internal function call. */;