This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/24756] New: pointer arithmetic on ia32 uses signed divide


By using a signed divide for pointer arithmetic an incorerct value can be
obtained given sufficient distance between two pointers.

I have tested this on gcc 3.4 (RedHat EL4 update 1) and the same behaviour
persists.

# gcc -v -save-temps -Wall -o test ./test.c
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-118.7.2)
 /usr/lib/gcc-lib/i386-redhat-linux/2.96/cpp0 -lang-c -v -D__GNUC__=2
-D__GNUC_MINOR__=96 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__
-D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__NO_INLINE__ -Wall
-Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__tune_i386__ ./test.c
test.i
GNU CPP version 2.96 20000731 (Red Hat Linux 7.2 2.96-118.7.2) (cpplib) (i386
Linux/ELF)
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc-lib/i386-redhat-linux/2.96/include
 /usr/include
End of search list.
 /usr/lib/gcc-lib/i386-redhat-linux/2.96/cc1 test.i -quiet -dumpbase test.c
-Wall -version -o test.s
GNU C version 2.96 20000731 (Red Hat Linux 7.2 2.96-118.7.2)
(i386-redhat-linux) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.2
2.96-118.7.2).
./test.c:1: warning: initialization makes pointer from integer without a cast
./test.c:2: warning: initialization makes pointer from integer without a cast
./test.c:5: warning: return type defaults to `int'
./test.c: In function `main':
./test.c:6: warning: implicit declaration of function `printf'
./test.c:6: warning: unsigned int format, pointer arg (arg 2)
./test.c:6: warning: unsigned int format, pointer arg (arg 3)
./test.c:9: warning: unsigned int format, long unsigned int arg (arg 3)
./test.c:11: warning: control reaches end of non-void function
 as -V -Qy -o test.o test.s
GNU assembler version 2.11.90.0.8 (i386-redhat-linux) using BFD version
2.11.90.0.8
 /usr/lib/gcc-lib/i386-redhat-linux/2.96/collect2 -m elf_i386 -dynamic-linker
/lib/ld-linux.so.2 -o test
/usr/lib/gcc-lib/i386-redhat-linux/2.96/../../../crt1.o
/usr/lib/gcc-lib/i386-redhat-linux/2.96/../../../crti.o
/usr/lib/gcc-lib/i386-redhat-linux/2.96/crtbegin.o
-L/usr/lib/gcc-lib/i386-redhat-linux/2.96
-L/usr/lib/gcc-lib/i386-redhat-linux/2.96/../../.. test.o -lgcc -lc -lgcc
/usr/lib/gcc-lib/i386-redhat-linux/2.96/crtend.o
/usr/lib/gcc-lib/i386-redhat-linux/2.96/../../../crtn.o



# ./test 
 a = 0xcceb0000 b = 0x24100000
pointer         ( a - b )                                              
0xea36c000
non-pointer     ( ( ((unsigned long)a) - ((unsigned long)b) ) / 4)     
0x2a36c000

Assembler:
        .file   "test.c"
        .version        "01.01"
gcc2_compiled.:
.globl number
.data
        .align 4
        .type    number,@object
        .size    number,4
number:
        .long   -857014272
.globl mem_map
        .align 4
        .type    mem_map,@object
        .size    mem_map,4
mem_map:
        .long   605028352
                .section        .rodata
.LC0:
        .string " a = %#x b = %#x\n"
        .align 32
.LC1:
        .string "pointer\t\t( a - b )\t\t\t\t\t\t%#x\nnon-pointer\t( (
((unsigned long)a) - ((unsigned long)b) ) / 4)\t%#x\n"
.text
        .align 4
.globl main
        .type    main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        subl    $4, %esp
        pushl   mem_map
        pushl   number
        pushl   $.LC0
        call    printf
        addl    $16, %esp
        subl    $4, %esp
        movl    mem_map, %edx
        movl    number, %eax
        subl    %edx, %eax
        shrl    $2, %eax             <==== UNSIGNED (manual)
        pushl   %eax
        movl    mem_map, %edx
        movl    number, %eax
        subl    %edx, %eax
        movl    %eax, %eax
        sarl    $2, %eax             <==== SIGNED  (pointer)
        pushl   %eax
        pushl   $.LC1
        call    printf
        addl    $16, %esp
        leave
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-118.7.2)"


-- 
           Summary: pointer arithmetic on ia32 uses signed divide
           Product: gcc
           Version: 2.96 (redhat)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: j3p0uk at hotmail dot com


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]