[PATCH] Fix gimplification of post-{inc,dec}rement (PR c/29154)
Jakub Jelinek
jakub@redhat.com
Sat Sep 30 16:23:00 GMT 2006
Hi!
As the attached testcase showsif we have nested post-increments and the
value of the outer expression is used, we can generate bad code, the inner
post-increment side-effect are evaluated before outer post-increment's
side-effects and the outer side-effects modify a wrong object.
Fixed by making sure the outer side-effects are evaluated before the
inner ones.
Bootstrapped/regtested on 7 linux arches, ok for trunk/4.1?
2006-09-30 Jakub Jelinek <jakub@redhat.com>
PR c/29154
* gimplify.c (gimplify_self_mod_expr): Run inner expression's post
side effects after the outer expression's post side effects.
* gcc.c-torture/execute/20060929-1.c: New test.
--- gcc/gimplify.c.jj 2006-09-20 00:43:21.000000000 +0200
+++ gcc/gimplify.c 2006-09-29 17:15:06.000000000 +0200
@@ -1896,7 +1896,7 @@ gimplify_self_mod_expr (tree *expr_p, tr
bool want_value)
{
enum tree_code code;
- tree lhs, lvalue, rhs, t1;
+ tree lhs, lvalue, rhs, t1, post = NULL, *orig_post_p = post_p;
bool postfix;
enum tree_code arith_code;
enum gimplify_status ret;
@@ -1913,6 +1913,11 @@ gimplify_self_mod_expr (tree *expr_p, tr
else
postfix = false;
+ /* For postfix, make sure the inner expression's post side effects
+ are executed after side effects from this expression. */
+ if (postfix)
+ post_p = &post;
+
/* Add or subtract? */
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
arith_code = PLUS_EXPR;
@@ -1943,7 +1948,8 @@ gimplify_self_mod_expr (tree *expr_p, tr
if (postfix)
{
- gimplify_and_add (t1, post_p);
+ gimplify_and_add (t1, orig_post_p);
+ append_to_statement_list (post, orig_post_p);
*expr_p = lhs;
return GS_ALL_DONE;
}
--- gcc/testsuite/gcc.c-torture/execute/20060929-1.c.jj 2006-09-29 17:44:46.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/execute/20060929-1.c 2006-09-29 17:44:29.000000000 +0200
@@ -0,0 +1,44 @@
+/* PR c/29154 */
+
+extern void abort (void);
+
+void
+foo (int **p, int *q)
+{
+ *(*p++)++ = *q++;
+}
+
+void
+bar (int **p, int *q)
+{
+ **p = *q++;
+ *(*p++)++;
+}
+
+void
+baz (int **p, int *q)
+{
+ **p = *q++;
+ (*p++)++;
+}
+
+int
+main (void)
+{
+ int i = 42, j = 0;
+ int *p = &i;
+ foo (&p, &j);
+ if (p - 1 != &i || j != 0 || i != 0)
+ abort ();
+ i = 43;
+ p = &i;
+ bar (&p, &j);
+ if (p - 1 != &i || j != 0 || i != 0)
+ abort ();
+ i = 44;
+ p = &i;
+ baz (&p, &j);
+ if (p - 1 != &i || j != 0 || i != 0)
+ abort ();
+ return 0;
+}
Jakub
More information about the Gcc-patches
mailing list