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