diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 444e9039d1f9..fde381b07527 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2003-12-03 Jakub Jelinek + + * expr.c (store_constructor): Only set RTX_UNCHANGING_P for + read-only field if cleared is 0. + 2003-12-03 Nathanael Nerode * config.gcc: Mark obsolete targets for GCC 3.4. diff --git a/gcc/expr.c b/gcc/expr.c index c01378515f64..2f58cd2a2361 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4643,7 +4643,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) highest_pow2_factor (offset)); } - if (TREE_READONLY (field)) + /* If the constructor has been cleared, setting RTX_UNCHANGING_P + on the MEM might lead to scheduling the clearing after the + store. */ + if (TREE_READONLY (field) && !cleared) { if (GET_CODE (to_rtx) == MEM) to_rtx = copy_rtx (to_rtx); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b6883f55baff..2a30f30ccc3d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-12-03 Jakub Jelinek + + * gcc.dg/20031202-1.c: New test. + 2003-12-03 Mark Mitchell PR c++/10771 @@ -10,12 +14,12 @@ 2003-12-02 Giovanni Bajo - PR c++/10126 + PR c++/10126 * g++.dg/template/ptrmem8.C: New test. 2003-12-02 Giovanni Bajo - PR c++/12573 + PR c++/12573 * g++.dg/template/dependent-expr3.C: New test. 2003-12-01 James Lemke diff --git a/gcc/testsuite/gcc.dg/20031202-1.c b/gcc/testsuite/gcc.dg/20031202-1.c new file mode 100644 index 000000000000..424e01b5dd42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20031202-1.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-options "-O2 -mtune=i686" { target i?86-*-* } } */ + +extern void abort (void); +extern void exit (int); + +struct A { char p[6]; } __attribute__((packed)); +struct B { + struct A a; + void * const b; + struct A const * const c; + struct A const *d; +}; + +char v; + +int __attribute__((noinline)) +foo (struct B *b) +{ + int i; + for (i = 0; i < 6; ++i) + if (b->a.p[i]) + abort (); + if (b->b != &v || b->c || b->d) + abort (); + return 12; +} + +int __attribute__((noinline)) +bar (void *x) +{ + __asm __volatile ("" : "=r" (x) : "0" (x)); + struct B y = { .b = x, .c = (void *) 0 }; + return foo (&y) + 1; +} + +int +main (void) +{ + if (bar (&v) != 13) + abort (); + exit (0); +}