bug fix for c-torture test execute/bf-sign-2.c
Joern Rennecke
amylaar@cygnus.co.uk
Fri Oct 24 04:02:00 GMT 1997
> > The 31 bit unsigned bitfield is promoted to unsigned long int, not
> > signed long int. Hence the check fails. I found this for the d10v
> > port (which also supports 64 bit long long), and then checked the h8300:
> > it does the promotion the same way (but it doesn't show for a torture
> > test because the h8300 has only 32 bit long long, hence the test is skipped).
> Seems to me that the bug is in the compiler, not the test.
>
> Yes, ANSI doesn't mandate we handle this case since ANSI doesn't handle a
> bitfied > sizeof (int), but we want to do the "expected thing" if possible.
>
> So, it would seem to me, that for a 16bit int/32bit long target that a
> 31bit unsigned long field should promote to a "signed long" type.
Ok. Here is a patch to implement this:
Fri Oct 24 11:52:29 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
* c-typeck.c (default_conversion): If ints are smaller than
32 bit, promote bitfields larger than int, but smaller than
long to long / unsigned long.
Index: c-typeck.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/c-typeck.c,v
retrieving revision 1.2
diff -p -r1.2 c-typeck.c
*** c-typeck.c 1997/09/27 03:46:33 1.2
--- c-typeck.c 1997/10/24 10:54:44
*************** default_conversion (exp)
*** 1029,1034 ****
--- 1032,1060 ----
else
return convert (integer_type_node, exp);
}
+ /* Ansi/ISO doesn't specify what exactly is to be done for
+ bitfields larger than int. For hosts with ints thinner than
+ 32 bit
+ /* However, for hosts with ints thinner than 32 bit, we want to
+ promote bitfields thinner than long to long / unsigned long
+ to be consistent with 32 bit hosts.
+ Ansi/ISO doesn't specify what exactly is to be done for
+ bitfields larger than int, so there is no problem with these. */
+ else if (TYPE_PRECISION (integer_type_node) < 32
+ && TREE_CODE (exp) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (exp, 1)) == FIELD_DECL
+ && DECL_BIT_FIELD (TREE_OPERAND (exp, 1))
+ /* NB.: If the bitfield has exactly the same size as an
+ int, it does not get promoted.
+ ??? Should we make this dependent on -ansi? */
+ && low > TYPE_PRECISION (integer_type_node)
+ && low < TYPE_PRECISION (long_integer_type_node))
+ {
+ if (flag_traditional && TREE_UNSIGNED (type))
+ return convert (long_unsigned_type_node, exp);
+ else
+ return convert (long_integer_type_node, exp);
+ }
}
if (C_PROMOTING_INTEGER_TYPE_P (type))
More information about the Gcc
mailing list