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:
movlbuf.0, %eax
movl%eax, -4(%ebp)
.loc 1 13 0
cmpl$0, -4(%ebp)
jne .L2
.loc 1 14 0
movl8(%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)
callmalloc
movl%eax, buf.0
movlbuf.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