http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52558
Bug #: 52558 Summary: write introduction incorrect wrt the C++11 memory model Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: francesco.zappa.narde...@gmail.com The program below: int g_1 = 1; int g_2 = 0; int func_1(void) { int l; for (l = 0; (l != 4); l++) { if (g_1) return l; for (g_2 = 0; (g_2 >= 26); ++g_2) ; } } int main (int argc, char* argv[]) { func_1(); } is miscompiled by gcc -v : gcc version 4.7.0 20120215 (experimental) (GCC) (a recent svn snapshot) on x86-64 when -O2 is passed. Observe that the inner loop of func_1 is never executed, and this program should never perform any read/write to g_2. This means that func_1 might be executed in a thread in parallel with another thread that performs: g_2 = 42; printf ("%d",g_2) The resulting system is data-race free and the only value that should be printed is 42. However gcc -O2 generates the following x86-64 assembler for func_1: func_1: movl g_1(%rip), %edx movl g_2(%rip), %eax testl %edx, %edx jne .L2 movl $0, g_2(%rip) ret .L2: movl %eax, g_2(%rip) xorl %eax, %eax ret and this code always performs a write to g_2. If this asm code runs in parallel with "g_2 = 42; printf g_2", then the system might also print 0: this behaviour is introduced by the compiler and should not have happened. The command line to generate the assembler above is: $ g++ -std=c++11 read_and_write_introduced.c -O2 -S It might be the case that in the C++11 memory model it is safe for the compiler to introduce a write provided that there is an earlier write to the same location, but this testcase shows that introducing a write is unsafe whenever there are no previous writes. I labelled this as g++, but the bug will also affect the (future) c11 memory model. For reference: $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/home/riob/zappanar/tools/gcc-bin/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc-src/configure --prefix=/home/zappanar/tools/gcc-bin --with-gmp=/home/zappanar/tools/lib/ --with-mpfr=/home/zappanar/tools/lib/ --with-mpc=/home/zappanar/tools/lib/ --enable-languages=c,c++ Thread model: posix gcc version 4.7.0 20120215 (experimental) (GCC)