aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-01-15 09:03:53 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-01-15 09:03:53 +0100
commit241f845ab3717714234437e28bbaf2b1cc5f4426 (patch)
treecc04f22cb2a16aa9af9055fefe1388107a5c0f7b /gcc/c-family
parenteb6eb8623701589015d966a71970c1893a92884c (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/c-family/c-omp.c19
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;