https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63303

Szabolcs Nagy <nszabolcs at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nszabolcs at gmail dot com

--- Comment #13 from Szabolcs Nagy <nszabolcs at gmail dot com> ---
if gcc treats p-q as (ssize_t)p-(ssize_t)q and makes
optimization decisions based on signed int range then
that's broken and leads to wrong code gen.

e.g. gcc optimizes if(n - 0x7fffffff > 0).. away
(but not if(-0x7fffffff-1 - n > 0), but that's another
bug), so

$ cat bug.c
#include <sys/mman.h>
int main()
{
char *p = mmap((void*)(0x80000000-4096), 2*4096, PROT_READ|PROT_WRITE,
               MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
char *q = (void*)(0x7fffffff); // p+4095
if ((p+4096) - q > 0) return 0; // wrongly optimized away
return 1;
}

$ gcc-5.2-i386 -fomit-frame-pointer -fno-asynchronous-unwind-tables -O3 -S
bug.c
$ cat bug.s
        .file   "bug.c"
        .section        .text.unlikely,"ax",@progbits
.LCOLDB0:
        .section        .text.startup,"ax",@progbits
.LHOTB0:
        .p2align 2,,3
        .globl  main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $8, %esp
        pushl   $0
        pushl   $0
        pushl   $-1
        pushl   $50
        pushl   $3
        pushl   $8192
        pushl   $2147479552
        call    mmap
        addl    $32, %esp
        movl    $1, %eax
        movl    -4(%ebp), %ecx
        leave
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .section        .text.unlikely
.LCOLDE0:
        .section        .text.startup
.LHOTE0:
        .ident  "GCC: (GNU) 5.2.0"
        .section        .note.GNU-stack,"",@progbits

after the mmap call %eax is unconditionally set to 1.

at runtime the mmap succeeds and the returned object
crosses the 0x80000000 boundary, so the return value is
incorrect.

(i found this bug report after incorrectly getting SIGILL
at ptrdiffs with
-fsanitize=undefined -fsanitize-undefined-trap-on-error )

Reply via email to