aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-10-02 08:11:49 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2006-10-02 08:11:49 +0200
commit82181741c1deec0c06b7df21d7ec51781536ec12 (patch)
tree4e87301cda3476dbc9491d3c3b3aab872e6e68e1 /gcc
parent51a203d95e956aacdb9c6432f9fabdee3c20276e (diff)
downloadgcc-82181741c1deec0c06b7df21d7ec51781536ec12.zip
gcc-82181741c1deec0c06b7df21d7ec51781536ec12.tar.gz
gcc-82181741c1deec0c06b7df21d7ec51781536ec12.tar.bz2
re PR c/29154 (*(* ppointer++)++ = *pointer++ generates bad code)
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. From-SVN: r117366
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimplify.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20060929-1.c44
4 files changed, 63 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14e3af7..8c10757 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-10-02 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.
+
2006-10-01 Sandra Loosemore <sandra@codesourcery.com>
* tree.h (DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): Fix
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 9db673a..84c7219 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1896,7 +1896,7 @@ gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
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, tree *pre_p, tree *post_p,
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, tree *pre_p, tree *post_p,
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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 696d0ab..c3efeac 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-10-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/29154
+ * gcc.c-torture/execute/20060929-1.c: New test.
+
2006-10-01 Mark Mitchell <mark@codesourcery.com>
PR c++/29105
diff --git a/gcc/testsuite/gcc.c-torture/execute/20060929-1.c b/gcc/testsuite/gcc.c-torture/execute/20060929-1.c
new file mode 100644
index 0000000..76c447f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20060929-1.c
@@ -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;
+}