It fails on the following versions of gcc.

arm-elf target, i686-pc-linux-gnu host:
                   gcc version 3.3.2
i386-redhat-linux: gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7)
i486-linux:        gcc version 3.3.4 (Debian 1:3.3.4-13)
powerpc-macintosh: gcc version 3.3 20030304 (Apple Computer, Inc. build 1640)

Detailed -v output at the end.


Test case:
// gcc  -g -O0   variable-structure.c   -o variable-structure

void *malloc(unsigned int size);

void f(int length)
{
    static void *buf;
    struct {
        int x;
        char y[length];
    } *z = buf;
    if (!z)
        z = buf = malloc(sizeof(*z)*2);
    z[1].x = length;
}

int main()
{
    int i;
    for (i=0; i<2; i++) {
        f(100);
        malloc(100);
    }
}


On all the architectures I tested the sizeof() calculation (implicit in the    
"z[1].x = length" line) uses a variable that is initialized in the
"malloc(sizeof(*z)*2)" sizeof calculation. The problem is that the first
sizeof() is in an "if" and so only happens once. The for loop in main() is just
set up to make sure that the unitialized variable gets trashed between calls to 
f().

On my x86 debian box the output looks like this:

f:
.LFB3:
        .loc 1 7 0
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $24, %esp
.LCFI2:
        .loc 1 12 0
.LBB2:
        movl    buf.0, %eax
        movl    %eax, -4(%ebp)
        .loc 1 13 0
        cmpl    $0, -4(%ebp)
        jne     .L2
        .loc 1 14 0
        movl    8(%ebp), %eax
        decl    %eax
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        addl    $5, %eax
        movl    %eax, %edx
        shrl    $2, %edx
        andl    $3, %eax
        testl   %eax, %eax
        setne   %al
        movzbl  %al, %eax
        addl    %eax, %edx
        movl    %edx, %eax
        sall    $3, %eax
        movl    %eax, (%esp)
        call    malloc
        movl    %eax, buf.0
        movl    buf.0, %eax
        movl    %eax, -4(%ebp)
.L2:
        .loc 1 15 0
        movl    -8(%ebp), %eax
...etc.

The problem is here, where "-8(%ebp)" is used but only set up after the "jne
.L2" (so after the first call to f() it doesn't work).

The arm and powerpc compilers have the same problem.


My Debian x86 machine:
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.4/specs
Configured with: ../src/configure -v
--enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr
--mandir=/usr/share/man --infodir=/usr/share/info
--with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --with-system-zlib
--enable-nls --without-included-gettext --enable-__cxa_atexit
--enable-clocale=gnu --enable-debug --enable-java-gc=boehm
--enable-java-awt=xlib --enable-objc-gc i486-linux
Thread model: posix
gcc version 3.3.4 (Debian 1:3.3.4-13)

A friends x86 Fedora machine:
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --disable-libunwind-exceptions --with-system-zlib
--enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7)

My Mac:
$ gcc -v
Reading specs from /usr/libexec/gcc/darwin/ppc/3.3/specs
Thread model: posix
gcc version 3.3 20030304 (Apple Computer, Inc. build 1640)


My arm-elf cross compiler (on my debian x86 box):
$ arm-elf-gcc -v
Reading specs from /usr/lib/gcc-lib/arm-elf/3.3.2/specs
Configured with: ../source-tree/gcc-3.3.2/configure --host=i686-pc-linux-gnu
--target=arm-elf --enable-languages=c,c++ --with-cpu=arm9tdmi --prefix=/usr
--with-gxx-include-dir=/usr/arm-elf/include/g++-v3
--includedir=/usr/arm-elf/include
--with-headers=/source-tree/gcc-3.3.2/gcc/gincludes --enable-multilib
--enable-big-endian
Thread model: single
gcc version 3.3.2

-- 
           Summary: Gcc outputs sizeof calculation code that uses
                    unitialized memory
           Product: gcc
           Version: 3.3.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: david+gcc at porkrind dot org
                CC: gcc-bugs at gcc dot gnu dot org
  GCC host triplet: i386-redhat-linux, i486-linux, i686-pc-linux-gnu,
                    powerpc-apple-
GCC target triplet: i386-redhat-linux, i486-linux, arm-elf, powerpc-apple-
                    darwin


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

Reply via email to