public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/15634] New: Structure pointer arithmetic produces incorrect result
@ 2004-05-25 14:45 mike dot meyer at ncr dot com
  2004-05-25 14:45 ` [Bug c/15634] " falk at debian dot org
  0 siblings, 1 reply; 2+ messages in thread
From: mike dot meyer at ncr dot com @ 2004-05-25 14:45 UTC (permalink / raw)
  To: gcc-bugs

Structure pointer arithmetic produces incorrect results.  This appears to only 
affect pointers to structures which have sizes that are not a power of 2.  This 
has been seen in GCC versions 3.2.3 and 3.3.2.

The following code illustrates the issue:

typedef struct{
        long    field1;
        long    field2;
        long    filed3;
} test_ptr_t;

char            array[4*1024];

int
main(void)
{
        test_ptr_t      *ptr1;
        test_ptr_t      *ptr2;


        /* Less than 1 structure can fit in this space. 
           Size is not a multiple of structure size.            */
        ptr1 = (test_ptr_t *)&array[4];
        ptr2 = (test_ptr_t *)&array[sizeof(*ptr1)+2];

        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr1, ptr2,  ptr1 - ptr2, sizeof(*ptr1));
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr2, ptr1,  ptr2 - ptr1, sizeof(*ptr1));

        /* 1 structure can fit in this space.  Size is not
           a multiple of structure size. */
        ptr1 = (test_ptr_t *)&array[0];
        ptr2 = (test_ptr_t *)&array[sizeof(*ptr1) + 1];
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr1, ptr2,  ptr1 - ptr2, sizeof(*ptr1));
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr2, ptr1,  ptr2 - ptr1, sizeof(*ptr1));

        /* 1 structure can fit in this space. Size is a
           multiple of structure size.                  */
        ptr1 = (test_ptr_t *)&array[0];
        ptr2 = (test_ptr_t *)&array[sizeof(*ptr1)];
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr1, ptr2,  ptr1 - ptr2, sizeof(*ptr1));
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr2, ptr1,  ptr2 - ptr1, sizeof(*ptr1));
}

Output from gcc:

gcc -v -save-temps -o ptrtest ptrtest.c
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-
checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-24)
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/cpp0 -lang-c -v -D__GNUC__=3 -
D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=3 -D__GXX_ABI_VERSION=102 -D__ELF__ -
Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__ -
D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -
Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i386__ ptrtest.c 
ptrtest.i
GNU CPP version 3.2.3 20030502 (Red Hat Linux 3.2.3-24) (cpplib) (i386 
Linux/ELF)
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/include
 /usr/include
End of search list.
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/cc1 -fpreprocessed ptrtest.i -quiet -
dumpbase ptrtest.c -version -o ptrtest.s
GNU CPP version 3.2.3 20030502 (Red Hat Linux 3.2.3-24) (cpplib) (i386 
Linux/ELF)
GNU C version 3.2.3 20030502 (Red Hat Linux 3.2.3-24) (i386-redhat-linux)
        compiled by GNU C version 3.2.3 20030502 (Red Hat Linux 3.2.3-24).
 as -V -Qy -o ptrtest.o ptrtest.s
GNU assembler version 2.14.90.0.4 (i386-redhat-linux) using BFD version 
2.14.90.0.4 20030523

 /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/collect2 --eh-frame-hdr -m elf_i386 -
dynamic-linker /lib/ld-linux.so.2 -o ptrtest /usr/lib/gcc-lib/i386-redhat-
linux/3.2.3/../../../crt1.o /usr/lib/gcc-lib/i386-redhat-
linux/3.2.3/../../../crti.o /usr/lib/gcc-lib/i386-redhat-
linux/3.2.3/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.3 -
L/usr/lib/gcc-lib/i386-redhat-linux/3.2.3/../../.. ptrtest.o -lgcc -lgcc_eh -
lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i386-redhat-
linux/3.2.3/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/../../../crtn.o
$ ./ptrtest
0x80497a4 - 0x80497ae = -1 (struct size = 12)
0x80497ae - 0x80497a4 = 1431655766 (struct size = 12)
0x80497a0 - 0x80497ad = 1431655764 (struct size = 12)
0x80497ad - 0x80497a0 = 1 (struct size = 12)
0x80497a0 - 0x80497ac = -1 (struct size = 12)
0x80497ac - 0x80497a0 = 1 (struct size = 12)
$ 
$ cat ptrtest.i
# 1 "ptrtest.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "ptrtest.c"

typedef struct{
        long field1;
        long field2;
        long filed3;
} test_ptr_t;

char array[4*1024];

int
main(void)
{
        test_ptr_t *ptr1;
        test_ptr_t *ptr2;




        ptr1 = (test_ptr_t *)&array[4];
        ptr2 = (test_ptr_t *)&array[sizeof(*ptr1)+2];

        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr1, ptr2, ptr1 - ptr2, sizeof(*ptr1));
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr2, ptr1, ptr2 - ptr1, sizeof(*ptr1));

        ptr1 = (test_ptr_t *)&array[0];
        ptr2 = (test_ptr_t *)&array[sizeof(*ptr1) + 1];
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr1, ptr2, ptr1 - ptr2, sizeof(*ptr1));
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr2, ptr1, ptr2 - ptr1, sizeof(*ptr1));



        ptr1 = (test_ptr_t *)&array[0];
        ptr2 = (test_ptr_t *)&array[sizeof(*ptr1)];
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr1, ptr2, ptr1 - ptr2, sizeof(*ptr1));
        printf("0x%x - 0x%x = %d (struct size = %d)\n",
                ptr2, ptr1, ptr2 - ptr1, sizeof(*ptr1));
}
$ 
$ cat ptrtest.s
        .file   "ptrtest.c"
        .section        .rodata
        .align 32
.LC0:
        .string "0x%x - 0x%x = %d (struct size = %d)\n"
        .text
.globl main
        .type   main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        movl    $array+4, -4(%ebp)
        movl    $array+14, -8(%ebp)
        subl    $12, %esp
        pushl   $12
        movl    -8(%ebp), %edx
        movl    -4(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %ecx
        sarl    $2, %ecx
        movl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        movl    %eax, %edx
        sall    $8, %edx
        addl    %edx, %eax
        movl    %eax, %edx
        sall    $16, %edx
        addl    %edx, %eax
        sall    $1, %eax
        addl    %ecx, %eax
        pushl   %eax
        pushl   -8(%ebp)
        pushl   -4(%ebp)
        pushl   $.LC0
        call    printf
        addl    $32, %esp
        subl    $12, %esp
        pushl   $12
        movl    -4(%ebp), %edx
        movl    -8(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %ecx
        sarl    $2, %ecx
        movl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        movl    %eax, %edx
        sall    $8, %edx
        addl    %edx, %eax
        movl    %eax, %edx
        sall    $16, %edx
        addl    %edx, %eax
        sall    $1, %eax
        addl    %ecx, %eax
        pushl   %eax
        pushl   -4(%ebp)
        pushl   -8(%ebp)
        pushl   $.LC0
        call    printf
        addl    $32, %esp
        movl    $array, -4(%ebp)
        movl    $array+13, -8(%ebp)
        subl    $12, %esp
        pushl   $12
        movl    -8(%ebp), %edx
        movl    -4(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %ecx
        sarl    $2, %ecx
        movl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        movl    %eax, %edx
        sall    $8, %edx
        addl    %edx, %eax
        movl    %eax, %edx
        sall    $16, %edx
        addl    %edx, %eax
        sall    $1, %eax
        addl    %ecx, %eax
        pushl   %eax
        pushl   -8(%ebp)
        pushl   -4(%ebp)
        pushl   $.LC0
        call    printf
        addl    $32, %esp
        subl    $12, %esp
        pushl   $12
        movl    -4(%ebp), %edx
        movl    -8(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %ecx
        sarl    $2, %ecx
        movl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        movl    %eax, %edx
        sall    $8, %edx
        addl    %edx, %eax
        movl    %eax, %edx
        sall    $16, %edx
        addl    %edx, %eax
        sall    $1, %eax
        addl    %ecx, %eax
        pushl   %eax
        pushl   -4(%ebp)
        pushl   -8(%ebp)
        pushl   $.LC0
        call    printf
        addl    $32, %esp
        movl    $array, -4(%ebp)
        movl    $array+12, -8(%ebp)
        subl    $12, %esp
        pushl   $12
        movl    -8(%ebp), %edx
        movl    -4(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %ecx
        sarl    $2, %ecx
        movl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        movl    %eax, %edx
        sall    $8, %edx
        addl    %edx, %eax
        movl    %eax, %edx
        sall    $16, %edx
        addl    %edx, %eax
        sall    $1, %eax
        addl    %ecx, %eax
        pushl   %eax
        pushl   -8(%ebp)
        pushl   -4(%ebp)
        pushl   $.LC0
        call    printf
        addl    $32, %esp
        subl    $12, %esp
        pushl   $12
        movl    -4(%ebp), %edx
        movl    -8(%ebp), %eax
        subl    %edx, %eax
        movl    %eax, %ecx
        sarl    $2, %ecx
        movl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        sall    $2, %eax
        addl    %ecx, %eax
        movl    %eax, %edx
        sall    $8, %edx
        addl    %edx, %eax
        movl    %eax, %edx
        sall    $16, %edx
        addl    %edx, %eax
        sall    $1, %eax
        addl    %ecx, %eax
        pushl   %eax
        pushl   -4(%ebp)
        pushl   -8(%ebp)
        pushl   $.LC0
        call    printf
        addl    $32, %esp
        leave
        ret
.Lfe1:
        .size   main,.Lfe1-main
        .comm   array,4096,32
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-24)"
$ 

The results from this same code compiled using the Microsoft C compiler 
(VS .net 2003; version 7.1.3088).

0x4284e4 - 0x4284ec = 0 (struct size = 12)
0x4284ec - 0x4284e4 = 0 (struct size = 12)
0x4284e0 - 0x4284ee = -1 (struct size = 12)
0x4284ee - 0x4284e0 = 1 (struct size = 12)
0x4284e0 - 0x4284ec = -1 (struct size = 12)
0x4284ec - 0x4284e0 = 1 (struct size = 12)

The results from a Metaware compiler compiling the same code:

$ cc -V
(cc:) NCR High Performance C Compiler R3.0 (SCDE 3.03.00) 
(cc:) No files specified.
$ cc -o ptrtest ptrtest.c
NCR High Performance C Compiler R3.0c 
(c) Copyright 1994-98, NCR Corporation
(c) Copyright 1987-98, MetaWare Incorporated
w "ptrtest.c",L11/C1(#72):      main: Function has no return statement.
No errors   1 warning   
$ ./ptrtest  
0x8049774 - 0x804977e = 0 (struct size = 12)
0x804977e - 0x8049774 = 0 (struct size = 12)
0x8049770 - 0x804977d = -1 (struct size = 12)
0x804977d - 0x8049770 = 1 (struct size = 12)
0x8049770 - 0x804977c = -1 (struct size = 12)
0x804977c - 0x8049770 = 1 (struct size = 12)
$

-- 
           Summary: Structure pointer arithmetic produces incorrect result
           Product: gcc
           Version: 3.2.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mike dot meyer at ncr dot com
                CC: gcc-bugs at gcc dot gnu dot org


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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug c/15634] Structure pointer arithmetic produces incorrect result
  2004-05-25 14:45 [Bug c/15634] New: Structure pointer arithmetic produces incorrect result mike dot meyer at ncr dot com
@ 2004-05-25 14:45 ` falk at debian dot org
  0 siblings, 0 replies; 2+ messages in thread
From: falk at debian dot org @ 2004-05-25 14:45 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From falk at debian dot org  2004-05-24 18:16 -------
Invalid, since you use not properly aligned pointers.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-05-24 18:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-25 14:45 [Bug c/15634] New: Structure pointer arithmetic produces incorrect result mike dot meyer at ncr dot com
2004-05-25 14:45 ` [Bug c/15634] " falk at debian dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).