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