diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-01-15 09:03:53 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-01-15 09:03:53 +0100 |
commit | 241f845ab3717714234437e28bbaf2b1cc5f4426 (patch) | |
tree | cc04f22cb2a16aa9af9055fefe1388107a5c0f7b /gcc/c-family | |
parent | eb6eb8623701589015d966a71970c1893a92884c (diff) | |
download | gcc-241f845ab3717714234437e28bbaf2b1cc5f4426.zip gcc-241f845ab3717714234437e28bbaf2b1cc5f4426.tar.gz gcc-241f845ab3717714234437e28bbaf2b1cc5f4426.tar.bz2 |
re PR c/58943 (wrong calculation of indirect structure member arithmetic via function call)
PR c/58943
* c-typeck.c (build_modify_expr): For lhs op= rhs, if rhs has side
effects, preevaluate rhs using SAVE_EXPR first.
* c-omp.c (c_finish_omp_atomic): Set in_late_binary_op around
build_modify_expr with non-NOP_EXPR opcode. Handle return from it
being COMPOUND_EXPR.
(c_finish_omp_for): Handle incr being COMPOUND_EXPR with first
operand a SAVE_EXPR and second MODIFY_EXPR.
* gcc.c-torture/execute/pr58943.c: New test.
* gcc.dg/tree-ssa/ssa-fre-33.c (main): Avoid using += in the test.
From-SVN: r206620
Diffstat (limited to 'gcc/c-family')
-rw-r--r-- | gcc/c-family/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-family/c-omp.c | 19 |
2 files changed, 27 insertions, 1 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index d9b69b3..80dd632 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,12 @@ +2014-01-15 Jakub Jelinek <jakub@redhat.com> + + PR c/58943 + * c-omp.c (c_finish_omp_atomic): Set in_late_binary_op around + build_modify_expr with non-NOP_EXPR opcode. Handle return from it + being COMPOUND_EXPR. + (c_finish_omp_for): Handle incr being COMPOUND_EXPR with first + operand a SAVE_EXPR and second MODIFY_EXPR. + 2014-01-09 Jakub Jelinek <jakub@redhat.com> PR target/58115 diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index ac380ee..4ce51e4 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -136,7 +136,7 @@ c_finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode, tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst) { - tree x, type, addr; + tree x, type, addr, pre = NULL_TREE; if (lhs == error_mark_node || rhs == error_mark_node || v == error_mark_node || lhs1 == error_mark_node @@ -194,9 +194,18 @@ c_finish_omp_atomic (location_t loc, enum tree_code code, rhs = build2_loc (loc, opcode, TREE_TYPE (lhs), rhs, lhs); opcode = NOP_EXPR; } + bool save = in_late_binary_op; + in_late_binary_op = true; x = build_modify_expr (loc, lhs, NULL_TREE, opcode, loc, rhs, NULL_TREE); + in_late_binary_op = save; if (x == error_mark_node) return error_mark_node; + if (TREE_CODE (x) == COMPOUND_EXPR) + { + pre = TREE_OPERAND (x, 0); + gcc_assert (TREE_CODE (pre) == SAVE_EXPR); + x = TREE_OPERAND (x, 1); + } gcc_assert (TREE_CODE (x) == MODIFY_EXPR); rhs = TREE_OPERAND (x, 1); @@ -264,6 +273,8 @@ c_finish_omp_atomic (location_t loc, enum tree_code code, x = omit_one_operand_loc (loc, type, x, rhs1addr); } + if (pre) + x = omit_one_operand_loc (loc, type, x, pre); return x; } @@ -555,6 +566,12 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv, incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr); break; + case COMPOUND_EXPR: + if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR + || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR) + break; + incr = TREE_OPERAND (incr, 1); + /* FALLTHRU */ case MODIFY_EXPR: if (TREE_OPERAND (incr, 0) != decl) break; |