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



             Bug #: 56098

           Summary: conditional write through volatile pointer produces

                    unintended read

    Classification: Unclassified

           Product: gcc

           Version: 4.7.2

            Status: UNCONFIRMED

          Severity: major

          Priority: P3

         Component: c

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: wer...@almesberger.net





If compiled with -O2 or greater and without -fno-strict-aliasing, the following

code



volatile int *ptr;



void problem(int flag)

{

        *ptr = 1;

        if (flag)

                *ptr = 2;

}



produces an unintended read, as if the "if" statement had continued with



        else

                *ptr = *ptr;



Code generated by gcc 4.7.2 on Ubuntu on x86-64 when invoked with

gcc-4.7 -Wall -Wextra -O2 -S bug.c



...

problem:

.LFB0:

        .cfi_startproc

        movq    ptr(%rip), %rax

        testl   %edi, %edi

        movl    $2, %edx

        movl    $1, (%rax)

        jne     .L2

        movl    (%rax), %edx    <<< unexpected

.L2:

        movl    %edx, (%rax)

        ret

        .cfi_endproc

...



This happens with

- gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 for x86-64,

- gcc-4.7 (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 for x86-64,

- mipsel-openwrt-linux-gcc (Linaro GCC 4.6-2012.02) 4.6.3 20120201 (prerelease)

for MIPS,

and I've had someone confirm it for an ARM target (without further details) as

well.



-Os instead of -O2 has the same effect. The unintended read disappears if

optimizing with -O1 or less, or with -fno-strict-aliasing.



This bears a striking resemblance to Bug 15456 and maybe Bug 5395, except that

these were for C++ while this is plain C.

Reply via email to