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