From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux alpha; en-US; rv:0.9.7) Gecko/20011226 Description of problem: this showed up in Mozilla builds. at some point a negative 32-bit intermediate was improperly promoted to a 64 number. see code below and the given URL. relevant rpms: gcc-2.96-87 gcc-c++-2.96-87 gcc-objc-2.96-87 glibc-2.2.4-19.3 kernel-2.4.3-12 kernel-headers-2.4.3-12 libstdc++-2.96-87 libstdc++-devel-2.96-87 Version-Release number of selected component (if applicable): 2.96-87 How reproducible: Always Steps to Reproduce: 1.save code to file 2.compile (gcc -o test test.cpp) 3.run Actual Results: es[1] = 0 &es[1] = 0x11ffff889 expand-1-j = 1 &es[expand-1-j] = 0x21ffff889 sL = &es[expand-1-j] - &es[1] = 4294967296 &es[expand-1-j] - &es[1] = 0 es[expand-j-1]=0 Segmentation fault Expected Results: &es[1] = 0x11ffff889 expand-1-j = 1 &es[expand-1-j] = 0x11ffff889 sL = &es[expand-1-j] - &es[1] = 0 &es[expand-1-j] - &es[1] = 0 es[expand-j-1]=0 es[expand-1-j]=0 Additional info: // test.cpp #include <stdio.h> int main () { unsigned char *es; unsigned char exp_buffer[2]; long sL; unsigned int j; int expand; es=exp_buffer; j=0; expand=2; es[0]=0; es[1]=0; printf ("es[1] = %d\n", es[1]); printf ("&es[1] = %p\n", &es[1]); printf ("expand-1-j = %d\n", expand-1-j); printf ("&es[expand-1-j] = %p\n", &es[expand-1-j]); sL = &es[expand-1-j] - &es[1]; printf ("sL = &es[expand-1-j] - &es[1]\n = %ld\n", sL); printf ("&es[expand-1-j] - &es[1] = %d\n", &es[expand-1-j]-&es[1]); printf ("es[expand-j-1]=%d\n",es[expand-j-1]); printf ("es[expand-1-j]=%d\n",es[expand-1-j]); return 0; }
This test case don't provide show the bug with gcc-2.96-98.
this has come up again in Mozilla (bug 127455), this time with pointer arithmetic. http://bugzilla.mozilla.org/show_bug.cgi?id=127455
Simpler case showing more extereme behavior from Mozilla bug 127455: ------------------------------------------ #include <stdio.h> int main() { unsigned int j=1, i, *p; p = &i; p += -j; printf ("%p\n%p\n%ld\n", &i, p, p-&i); } ------------------------------------------ > 0x11ffff884 > 0x51ffff880 > 4294967295
If this is C++ only, then it is likely GCC PR c++/4401 which I've fixed in gcc 3.1 6 days ago. Will try to verify the patch in 2.96 and include it in next rpm...
The original report (with array indices) was c++ only. The one with pointer arithmetic is both c and c++. I figured they were the same underlying problem, so I didn't file a new bug. Thanks for working on this.
The difference between the two is that the former is a compiler bug while the latter is correct behaviour. p += -j where -j is unsigned int is the same as p = p + ((unsigned int) (-j)); you need to cast it to some signed type before it is converted to ptrdiff_t.
The second case works ok on gcc-i686: > 0xbffff8d0 > 0xbffff8cc > -1 similar code in Mozilla worked on platforms other than Linux-Alpha (I'm not disagreeing, just confused)
Yeah, but i686 is 32-bit target where sizeof(int) == sizeof(void *). That's not the case on Alpha, nor IA-64, nor Sparc64, ...
yup. Compaq's cc compiler on OSF does the same as gcc on Linux
*** Bug 60443 has been marked as a duplicate of this bug. ***
An errata has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on the solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2002-055.html