problem with long long bitfields in varasm.c
Herman ten Brugge
Haj.Ten.Brugge@net.HCC.nl
Fri May 14 09:57:00 GMT 1999
Hello,
I discovered a bug in varasm.c that caused incorrect code to be
generated for long long bitfields.
I did sent this problem about 1/2 year ago but nothing happened until
now so I just resent it as a reminder.
I found a problem with long long bitfields. The problem occurred with the
following program:
struct tmp
{
long long int pad : 12;
long long int field : 52;
};
struct tmp tmp = {0x123LL, 0x123456789ABCDLL};
The code result for the i386 is:
tmp:
.byte 0x23
.byte 0xd1
.byte 0xbc
.byte 0x9a
.byte 0x78
.byte 0x55 <--- wrong
.byte 0x34
.byte 0x12
I found the bug in output_constructor in varasm.c. The value this_time and
shift are not calculated correctly.
I also found another bug. This bug only occures on the c4x where
HOST_BITS_PER_WIDE_INT == 32. It is illegal to do a shift with this value
so I clamped the value of this_time to HOST_BITS_PER_WIDE_INT-1.
Herman.
1999-05-14 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
* varasm.c (output_constructor) Fixed problem with calculating
this_time and shift for long long bitfields. Also fixed problem
with shiftcount equal to HOST_BITS_PER_WIDE_INT.
--- varasm.c.org Fri May 14 18:52:55 1999
+++ varasm.c Fri May 14 18:53:04 1999
@@ -4192,6 +4192,7 @@ output_constructor (exp, size)
(all part of the same byte). */
this_time = MIN (end_offset - next_offset,
BITS_PER_UNIT - next_bit);
+ this_time = MIN (this_time, HOST_BITS_PER_WIDE_INT-1);
if (BYTES_BIG_ENDIAN)
{
/* On big-endian machine, take the most significant bits
@@ -4203,8 +4204,7 @@ output_constructor (exp, size)
if (shift < HOST_BITS_PER_WIDE_INT
&& shift + this_time > HOST_BITS_PER_WIDE_INT)
{
- this_time -= (HOST_BITS_PER_WIDE_INT - shift);
- shift = HOST_BITS_PER_WIDE_INT;
+ this_time = (HOST_BITS_PER_WIDE_INT - shift);
}
/* Now get the bits from the appropriate constant word. */
@@ -4236,8 +4236,7 @@ output_constructor (exp, size)
if (shift < HOST_BITS_PER_WIDE_INT
&& shift + this_time > HOST_BITS_PER_WIDE_INT)
{
- this_time -= (HOST_BITS_PER_WIDE_INT - shift);
- shift = HOST_BITS_PER_WIDE_INT;
+ this_time = (HOST_BITS_PER_WIDE_INT - shift);
}
/* Now get the bits from the appropriate constant word. */
More information about the Gcc-patches
mailing list