diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-10-11 09:36:07 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-10-11 09:36:07 +0200 |
commit | 1a37b6d9a7e57c71b1bfe449ebd275eb408117fb (patch) | |
tree | fe29653bb010efc768398510adcd8af902405b71 /gcc/cp/cp-gimplify.c | |
parent | 1e99e6fe6bb61ad2011030324cfdf84d2a67e75d (diff) | |
download | gcc-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.c | 25 |
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. */; |