Bug 58746 - 32-bit integer array indices improperly promoted to 64-bit in c++
Summary: 32-bit integer array indices improperly promoted to 64-bit in c++
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
(Show other bugs)
Version: 7.1
Hardware: alphaev6 Linux
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL: http://bugzilla.mozilla.org/show_bug....
: 60443 (view as bug list)
Depends On:
TreeView+ depends on / blocked
Reported: 2002-01-23 23:40 UTC by Andrew Schultz
Modified: 2007-04-18 16:39 UTC (History)
0 users

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

Attachments (Terms of Use)

External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2002:055 contract SHIPPED_LIVE Updated version of GCC 2.96-RH now available 2002-04-02 05:00:00 UTC

Description Andrew Schultz 2002-01-23 23:40:57 UTC
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:

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1.save code to file
2.compile (gcc -o test test.cpp)

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
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

Additional info:

// test.cpp

#include <stdio.h>

int main ()
   unsigned char *es;
   unsigned char exp_buffer[2];

   long sL;

   unsigned int j;
   int expand;


   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 16:37:42 UTC
This test case don't provide show the bug with gcc-2.96-98.

Comment 2 Andrew Schultz 2002-02-25 22:55:41 UTC
this has come up again in Mozilla (bug 127455), this time with pointer arithmetic.

Comment 3 Andrew Schultz 2002-02-26 21:16:36 UTC
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 23:07:52 UTC
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 23:20:51 UTC
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 11:26:18 UTC
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 15:15:13 UTC
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 15:19:27 UTC
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 15:37:43 UTC
yup.  Compaq's cc compiler on OSF does the same as gcc on Linux

Comment 10 Jakub Jelinek 2002-03-04 14:24:13 UTC
*** Bug 60443 has been marked as a duplicate of this bug. ***

Comment 11 Bill Nottingham 2002-07-26 21:47:27 UTC
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.


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