From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10735 invoked by alias); 12 Mar 2012 10:26:16 -0000 Received: (qmail 10722 invoked by uid 22791); 12 Mar 2012 10:26:14 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,TW_SV X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 12 Mar 2012 10:26:00 +0000 From: "francesco.zappa.nardelli at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/52558] New: write introduction incorrect wrt the C++11 memory model Date: Mon, 12 Mar 2012 10:26:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: francesco.zappa.nardelli at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-03/txt/msg00834.txt.bz2 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)