This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Bootstrap failure because of warning in tc-i386.c
- From: Nick Clifton <nickc at redhat dot com>
- To: hjl dot tools at gmail dot com
- Cc: binutils at sourceware dot org
- Date: Fri, 18 Dec 2015 08:57:43 +0000
- Subject: Bootstrap failure because of warning in tc-i386.c
- Authentication-results: sourceware.org; auth=none
Hi H,J.
I was trying to bootstrap the current mainline FSF gcc sources
yesterday, using a combined tree with the latest binutils sources,
when I ran into this error:
gas/config/tc-i386.c: In function 'optimize_imm':
gas/config/tc-i386.c:4222:53: error: result of '2l << 31' requires 34 bits to represent, but 'long int' only has 32 bits [-Werror=shift-overflow=]
&& ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1))
^~
gas/config/tc-i386.c: In function 'optimize_disp':
gas/config/tc-i386.c:4310:32: error: result of '2l << 31' requires 34 bits to represent, but 'long int' only has 32 bits [-Werror=shift-overflow=]
&& (op_disp & ~(((offsetT) 2 << 31) - 1)) == 0)
^~
gas/config/tc-i386.c:4315:28: error: result of '2l << 31' requires 34 bits to represent, but 'long int' only has 32 bits [-Werror=shift-overflow=]
op_disp &= (((offsetT) 2 << 31) - 1);
^~
I tried adding a check on the size of offsetT but that was
insufficient - the compiler still complained even though the code
would never be executed. So in the end I opted for the patch below -
which makes the code conditional on BFD64 being defined. I am not
happy with the patch though, as it means that assembler will behave
differently depending upon whether it was built with 64-bit support
enabled or not. Please could you take a look and decide if the patch
is OK, or if a better solution is needed.
Cheers
Nick
PS. Bootstrapping was on an x86_64 box running Fedora 23.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 1573043..c2d8029 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4218,7 +4218,12 @@ optimize_imm (void)
i.op[op].imms->X_add_number =
(((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000);
}
- if ((i.types[op].bitfield.imm32)
+#ifdef BFD64
+ /* Note: if offsetT only holds 32 bits then the left shift below will
+ overflow. On the other hand if offsetT only holds 32 bits then
+ values bigger than that will be held as O_big not O_constant. */
+ if ((sizeof (offsetT) * CHAR_BIT) > 32
+ && i.types[op].bitfield.imm32
&& ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1))
== 0))
{
@@ -4226,6 +4231,7 @@ optimize_imm (void)
^ ((offsetT) 1 << 31))
- ((offsetT) 1 << 31));
}
+#endif
i.types[op]
= operand_type_or (i.types[op],
smallest_imm_type (i.op[op].imms->X_add_number));
@@ -4306,7 +4312,12 @@ optimize_disp (void)
op_disp = (((op_disp & 0xffff) ^ 0x8000) - 0x8000);
i.types[op].bitfield.disp64 = 0;
}
- if (i.types[op].bitfield.disp32
+#ifdef BFD64
+ /* Note: if offsetT only holds 32 bits then the left shift below will
+ overflow. On the other hand if offsetT only holds 32 bits then
+ values bigger than that will be held as O_big not O_constant. */
+ if ((sizeof (offsetT) * CHAR_BIT) > 32
+ && i.types[op].bitfield.disp32
&& (op_disp & ~(((offsetT) 2 << 31) - 1)) == 0)
{
/* If this operand is at most 32 bits, convert
@@ -4316,6 +4327,7 @@ optimize_disp (void)
op_disp = (op_disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31);
i.types[op].bitfield.disp64 = 0;
}
+#endif
if (!op_disp && i.types[op].bitfield.baseindex)
{
i.types[op].bitfield.disp8 = 0;