In a function using a global register variable, that calls a function through a function pointer, the -O optimization omits the last update of the register variable before the call. Environment: System: Linux linuix 2.4.21-99-default #1 Wed Sep 24 13:30:51 UTC 2003 i686 athlon i386 GNU/Linux Architecture: i686 <machine, os, target, libraries (multiple lines)> host: i586-suse-linux-gnu build: i586-suse-linux-gnu target: i586-suse-linux-gnu configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --enable-languages=c,c++,f77,objc,java,ada --disable-checking --enable-libgcj --with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit i586-suse-linux How-To-Repeat: ================================== bug.c =================================== register void** STACK __asm__("%ebx"); extern void** saved_STACK; extern unsigned int func (void); extern unsigned int (*func_pointer) (void); void lisp_completion_indirect () { STACK[0] = (void*)0; STACK++; func_pointer(); saved_STACK = STACK; STACK--; } void lisp_completion_direct () { STACK[0] = (void*)0; STACK++; func(); saved_STACK = STACK; STACK--; } ============================================================================ $ gcc -Wall -O -S bug.c In the resulting bug.s, you see that the increment of %ebx before the call is omitted in the lisp_completion_indirect function. ================================== bug.s =================================== .file "bug.c" .text .globl lisp_completion_indirect .type lisp_completion_indirect, @function lisp_completion_indirect: pushl %ebp movl %esp, %ebp subl $8, %esp movl $0, (%ebx) call *func_pointer movl %ebx, saved_STACK subl $4, %ebx leave ret .size lisp_completion_indirect, .-lisp_completion_indirect .globl lisp_completion_direct .type lisp_completion_direct, @function lisp_completion_direct: pushl %ebp movl %esp, %ebp subl $8, %esp movl $0, (%ebx) addl $4, %ebx call func movl %ebx, saved_STACK subl $4, %ebx leave ret .size lisp_completion_direct, .-lisp_completion_direct .ident "GCC: (GNU) 3.3.1 (SuSE Linux)" ============================================================================
Fix: The bug goes away if -O is not passed to gcc.
This is a dup of bug 7871 which is fixed for 3.3.4. *** This bug has been marked as a duplicate of 7871 ***