[Bug c++/52558] New: write introduction incorrect wrt the C++11 memory model
francesco.zappa.nardelli at gmail dot com
gcc-bugzilla@gcc.gnu.org
Mon Mar 12 10:26:00 GMT 2012
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: unassigned@gcc.gnu.org
ReportedBy: francesco.zappa.nardelli@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)
More information about the Gcc-bugs
mailing list