Bit-field patch, resurrected

Jim Wilson wilson@specifixinc.com
Thu Apr 15 03:11:00 GMT 2004


Joseph S. Myers wrote:
> Here at last is the resurrected bit-field patch to give bit-fields in
> C their proper types (integer types of the specified signedness and
> width, as required by the C standard, rather than the declared types);

Looking through this, the only thing I have an issue with is the 
REDUCE_BIT_FIELD stuff.

Changing expand_expr this way seems fragile.  It requires that anyone 
modifying expand_expr remember that they must call REDUCE_BIT_FIELD if 
they add a return statement, and of course people will forget to do 
this, which means this support will break occasionally.

It would be cleaner to do this in the actual arithmetic routines, like 
plus_constant, but that would require passing down precisions instead of 
modes, and that will result in a much bigger patch, which seems 
unnecessarily intrusive for what you are trying to do here.

An alternative to the expand_expr change would be to change the C front 
end.  You could modify build_binary_op and build_unary_op in c-typeck.c 
to add extra truncate/extend operations when the result type is a 
bit-field integer type.  This would avoid the need for the lang hook and 
any middle end changes, and might be a simpler change.  This assumes 
that all operations go through build_binary_op/build_unary_op though.  I 
am not sure if that is true.

I have another problem with this, which is that I believe this breaks 
the C89 support.  C99 defines the usual arithmetic promotions to say 
that if we have two integer types, we promote to the one with greater 
rank.  Thus if we have two bitfields, we promote the smaller bitfield to 
the larger one.  Thus the REDUCE_BIT_FIELD stuff is necessary for 
correct C99 support.  C89 however says nothing about bitfields.  It just 
says that we promote to which ever standard integer type can hold the 
value.  That means if we have two bitfields, we promote to int (assuming 
both are smaller than int).  Thus the REDUCE_BIT_FIELD stuff is wrong 
for C89.  I don't have a copy of the C90 standard, but I would be 
surprised if it was different than C89 in this area.  Thus your 
REDUCE_BIT_FIELD stuff is also wrong for C90.

This issue perhaps explains why your patches did not work for C++ and 
Java, as they are based on the C90 standard, and hence they probably 
don't have the same bit-field aware promotion rules that C99 has.

Fixing this might be a bit complicated.  common_type does the integral 
promotions.  It implicitly assumes that it can only get standard integer 
types, and thus it probably requires fixes to do the right thing for 
C89/C90 now.  Also, your c_common_signed_or_unsigned_type change seems 
wrong, as mode_only_needed should always be true for C89/C90.  There 
might also be other changes needed.

Another way to fix this might be to set 
LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS to true only for C99.  That would 
require making it a function though, as we can't check C front end 
variables in expr.c.  If the extra conversions are added in c-typeck.c, 
this language check could be done directly.  It isn't clear if this 
would work.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com



More information about the Gcc-patches mailing list