http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58409

            Bug ID: 58409
           Summary: wrong reordering of volatile writes
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: francesco.zappa.nardelli at gmail dot com

In the program below, at least according to the C11 standard, there is a
sequence point between the volatile store to g_3[0][0][0] and the volatile
store to *g_6 (that is, to the volatile int g_5).  As a consequence, the store
to g_3 should be performed before the store to g_5.

struct {
  volatile int f1;
} g_1, *g_2 = &g_1, g_3[1][1][1], **g_4 = &g_2;

volatile int g_5;

static volatile int *g_6 = &g_5;

int func_2 () {
  g_3[0][0][0] = **g_4;
  return 0;
}

int func_1 () {
  *g_6 = func_2 ();
  return 0;
}

void main () {
  func_1 ();
}

If the program is compiled with a recent svn trunk 

$ gcc -v
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-svn/configure --disable-bootstrap
--enable-languages=c,c++ 
Thread model: posix
gcc version 4.9.0 20130912 (experimental) (GCC) 

at optimisation level -O2 or -O3 then the generated assembler swaps the store
to g_5 with the store to g_3:

main:
        movq    g_4(%rip), %rax
        movq    (%rax), %rax
        movl    (%rax), %eax
        movl    $0, g_5(%rip)
        movl    %eax, g_3(%rip)
        ret

As far as I can tell, this reordering should be considered as a compiler bug. 
The same happens with gcc 4.8.1.

Reply via email to