In a function using a global register variable, that conditionally calls a nonreturning function, the GCSE omits the last update (a decrement) of the global register variable. 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 ==================================== typedef void * object; register object* STACK __asm__("%ebx"); typedef struct { object GCself; unsigned int tfl; unsigned int data[0]; } * Sstring; typedef struct { object GCself; unsigned int tfl; object enc_eol; object enc_towcs_error; object enc_tombs_error; object enc_charset; object enc_mblen; object enc_mbstowcs; object enc_wcslen; object enc_wcstombs; object enc_range; object enc_table; unsigned int min_bytes_per_char; unsigned int max_bytes_per_char; } * Encoding; extern void __attribute__((__noreturn__)) fehler_notreached (const char * file, unsigned int line); extern object allocate_s32string (unsigned int len); object n_char_to_string (const char * srcptr, unsigned int blen, object encoding) { const unsigned char * bptr = (const unsigned char *)srcptr; const unsigned char * bendptr = bptr + blen; unsigned int clen = ((unsigned int (*) (object, const unsigned char *, const unsigned char *)) ((const void *)((void*)((unsigned long)(((Encoding)((unsigned long)(encoding)-1))->enc_mblen)))))(encoding,bptr,bendptr); (STACK[0] = encoding, STACK += 1); { object obj = allocate_s32string(clen); encoding = (STACK -= 1, STACK[0]); { unsigned int * cptr = &((Sstring)((unsigned long)(obj)-1))->data[0]; unsigned int * cendptr = cptr + clen; ((void (*) (object, object, const unsigned char **, const unsigned char *, unsigned int**, unsigned int*)) ((const void *)((void*)((unsigned long)(((Encoding)((unsigned long)(encoding)-1))->enc_mbstowcs)))))(encoding,(object)0,&bptr,bendptr,&cptr,cendptr); if (!(cptr == cendptr)) fehler_notreached("encoding.d",1910); } return obj; } } ============================================================================ $ gcc -O2 -Wall -S bug.c In the resulting bug.s, you see that %ebx is incremented by 4 (this corresponds to the STACK += 1 expression) but is never decremented back by 4 (as expected from the STACK -= 1 expression two lines below). ================================= bug.s ==================================== .file "bug.c" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "encoding.d" .text .p2align 4,,15 .globl n_char_to_string .type n_char_to_string, @function n_char_to_string: pushl %ebp movl %esp, %ebp pushl %edi pushl %esi subl $36, %esp movl 8(%ebp), %eax movl 12(%ebp), %edx movl 16(%ebp), %edi addl %eax, %edx movl %edx, -20(%ebp) movl %eax, -16(%ebp) pushl %edx pushl %eax pushl %edi call *23(%edi) movl %eax, %esi movl %edi, (%ebx) movl %eax, (%esp) addl $4, %ebx call allocate_s32string movl %eax, -24(%ebp) movl -4(%ebx), %edi addl $7, %eax movl %eax, -12(%ebp) leal (%eax,%esi,4), %esi movl %esi, -28(%ebp) popl %ecx popl %eax leal -12(%ebp), %eax pushl %esi pushl %eax leal -16(%ebp), %eax movl -20(%ebp), %edx pushl %edx pushl %eax pushl $0 pushl %edi call *27(%edi) movl -28(%ebp), %eax addl $32, %esp cmpl %eax, -12(%ebp) jne .L4 movl -24(%ebp), %eax leal -8(%ebp), %esp popl %esi popl %edi popl %ebp ret .L4: pushl %eax pushl %eax pushl $1910 pushl $.LC0 call fehler_notreached .size n_char_to_string, .-n_char_to_string .ident "GCC: (GNU) 3.3.1 (SuSE Linux)" ============================================================================
Fix: The bug goes away if -fno-gcse is passed to gcc.
This is a dup of bug 7871 which is fixed in 3.3.4. *** This bug has been marked as a duplicate of 7871 ***