Fix integer promotion of bit-precise bit-fields.
Corrects miscompilation of bit-precise bit-fields cast to compatible types.
This change fixes a miscompilation issue in the C front-end related to bit-precise bit-fields. When a bit-precise integer bit-field is explicitly cast to a non-cv-qualified bit-precise integer of the same signedness and precision, the compiler was incorrectly applying integer promotions. The fix ensures that such casts are correctly handled by distinguishing them from direct use of the bit-field, preventing erroneous promotions. New test cases are added to verify the fix.
In Details
This commit addresses an issue in c-typeck.cc concerning the integer promotion of bit-fields of BITINT_TYPE. The problem occurs when a BITINT_TYPE field is cast to an identical BITINT_TYPE (which might involve convert_lvalue_to_rvalue and potentially a NON_LVALUE_EXPR). The existing logic in default_conversion incorrectly applies perform_integral_promotions to the result of the cast rather than the original expression when the cast's type matches the bit-field's underlying type. The fix ensures that perform_integral_promotions is applied to the original expression (`orig_exp…
- bit-precise bit-field
- A data structure within a C struct or union that occupies a specific number of bits, potentially fewer than a standard byte. 'Bit-precise' implies the size is exactly specified, not just rounded up to the nearest byte.
- integer promotion
- In C, smaller integer types (like
char,short, and bit-fields) are automatically converted tointorunsigned intwhen used in expressions, to prevent loss of information during arithmetic operations. - cv-qualified
- In C++, qualifiers like
constandvolatilethat specify properties of a type.cv-unqualifiedmeans these qualifiers are absent. - BITINT_TYPE
- GCC's internal representation for bit-precise integer types, used for bit-fields and other non-standard integer sizes.
- NON_LVALUE_EXPR
- An intermediate representation node in GCC that marks an expression that, while it might refer to a memory location, should be treated as a temporary value (rvalue) rather than an lvalue (which can be assigned to).