diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-10-21 11:47:09 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2019-10-21 11:47:09 +0000 |
commit | c8f5f6df0cb2338aea10b48210e867ba56705aa1 (patch) | |
tree | e20497fac6d5b8cea48f9396c67715e842a1f7df | |
parent | bff3f602b24a5caf1e0bbc1e05ff13f9127d4447 (diff) |
Backported from mainline
2019-10-04 Jakub Jelinek <jakub@redhat.com>
PR c++/91974
* cp-gimplify.c (cp_gimplify_expr) <case CALL_EXPR>: For
-fstrong-eval-order ensure CALL_EXPR_FN side-effects are evaluated
before any arguments. Additionally, ensure CALL_EXPR_FN that isn't
invariant nor OBJ_TYPE_REF nor SSA_NAME is forced into a temporary.
* g++.dg/cpp1z/eval-order5.C: New test.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@277256 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/eval-order5.C | 31 |
4 files changed, 59 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 21e54a597af..6b9f0930871 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,14 @@ 2019-10-21 Jakub Jelinek <jakub@redhat.com> Backported from mainline + 2019-10-04 Jakub Jelinek <jakub@redhat.com> + + PR c++/91974 + * cp-gimplify.c (cp_gimplify_expr) <case CALL_EXPR>: For + -fstrong-eval-order ensure CALL_EXPR_FN side-effects are evaluated + before any arguments. Additionally, ensure CALL_EXPR_FN that isn't + invariant nor OBJ_TYPE_REF nor SSA_NAME is forced into a temporary. + 2019-09-27 Jakub Jelinek <jakub@redhat.com> PR c++/88203 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 208892b9318..c3e37648c60 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -816,6 +816,21 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) case CALL_EXPR: ret = GS_OK; + if (flag_strong_eval_order == 2 + && CALL_EXPR_FN (*expr_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); + 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. */; else if (CALL_EXPR_REVERSE_ARGS (*expr_p)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1af702a38f0..368022961f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2019-10-21 Jakub Jelinek <jakub@redhat.com> Backported from mainline + 2019-10-04 Jakub Jelinek <jakub@redhat.com> + + PR c++/91974 + * g++.dg/cpp1z/eval-order5.C: New test. + 2019-10-01 Jakub Jelinek <jakub@redhat.com> PR c++/91925 diff --git a/gcc/testsuite/g++.dg/cpp1z/eval-order5.C b/gcc/testsuite/g++.dg/cpp1z/eval-order5.C new file mode 100644 index 00000000000..a8f06ed421a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/eval-order5.C @@ -0,0 +1,31 @@ +// PR c++/91974 +// { dg-do run } +// { dg-options "-fstrong-eval-order" } + +extern "C" void abort (); + +bool ok = false; + +void +foo (int x) +{ + if (x != 0) + abort (); + ok = true; +} + +void +bar (int) +{ + abort (); +} + +int +main () +{ + typedef void (*T) (int); + T fn = foo; + fn ((fn = bar, 0)); + if (fn != bar || !ok) + abort (); +} |