Bug 58746 - 32-bit integer array indices improperly promoted to 64-bit in c++
32-bit integer array indices improperly promoted to 64-bit in c++
Status: CLOSED ERRATA
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.1
alphaev6 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
http://bugzilla.mozilla.org/show_bug....
:
: 60443 (view as bug list)
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-01-23 18:40 EST by Andrew Schultz
Modified: 2007-04-18 12:39 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-07-26 17:47:27 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Andrew Schultz 2002-01-23 18:40:57 EST
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;
}
Comment 1 Christopher Blizzard 2002-01-24 11:37:42 EST
This test case don't provide show the bug with gcc-2.96-98.
Comment 2 Andrew Schultz 2002-02-25 17:55:41 EST
this has come up again in Mozilla (bug 127455), this time with pointer arithmetic.
http://bugzilla.mozilla.org/show_bug.cgi?id=127455
Comment 3 Andrew Schultz 2002-02-26 16:16:36 EST
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
Comment 4 Jakub Jelinek 2002-02-26 18:07:52 EST
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...
Comment 5 Andrew Schultz 2002-02-26 18:20:51 EST
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.
Comment 6 Jakub Jelinek 2002-02-27 06:26:18 EST
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.
Comment 7 Andrew Schultz 2002-02-27 10:15:13 EST
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)
Comment 8 Jakub Jelinek 2002-02-27 10:19:27 EST
Yeah, but i686 is 32-bit target where sizeof(int) == sizeof(void *).
That's not the case on Alpha, nor IA-64, nor Sparc64, ...
Comment 9 Andrew Schultz 2002-02-27 10:37:43 EST
yup.  Compaq's cc compiler on OSF does the same as gcc on Linux
Comment 10 Jakub Jelinek 2002-03-04 09:24:13 EST
*** Bug 60443 has been marked as a duplicate of this bug. ***
Comment 11 Bill Nottingham 2002-07-26 17:47:27 EDT
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

Note You need to log in before you can comment on or make changes to this bug.