[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