Greetings everybody, I'm seeking your advice on how to best solve a bug. The issue has to do with folding a bitfield contained in a union. Consider the following example:
union U { unsigned int a:24; unsigned int b:20; } u = { .a = 0x345678 }; int foo (void) { return u.b; } Currently, folding (fold_nonarray_ctor_reference and fold_ctor_reference) does the following: 1) Compute the difference between bit offset of a and b 2) Check that b's area is within a's area in memory 3) Do nothing if 1) yields a non-zero difference 4) Cast value stored in a according to the size of b by removing bits of highest weight (via VIEW_CONVERT_EXPR). This does not work for big endian targets since bitfield respect byte endianness (and I support word endianness) when layed out in memory. So a would end up like this (highest addresses on the right): -------------------------- | Ox34 | 0x56 | 0x78 | -------------------------- b would be the first two byte and then 4 highest bits of the third byte, as if memory was a sequence of bits instead bytes with highest value bits at the lowest "bit address" So the expected result would be 0x34567 but a cast as does VIEW_CONVERT_EXPR would return 0x45678. Forbidding folding in such case for big endian would work but I've been looking about a way to make bitfield folding also work for big endian. The approach I've been taking so far is to enhance native_encode_integer and native_interpret_integer to take a start parameter and express start and len as addressing bits rather than byte. Then in fold_nonarray_ctor_reference whenever the constructor is for a bitfield, that bitfield is encoded with its bit offset and bit length to target memory layout, then interpreted to the host as its type qualifier (unsigned int in the above example). Finally, a call to fold_ternary with a subcode of BIT_FIELD_REF is made which will encode that integer to the target memory layout as the type qualifier and decode it according to the bit offset and bit length of bitfield b. Note that juste replacing VIEW_CONVERT_EXPR by BIT_FIELD_REF has the advantage of allowing folding in simpler solutions like a union of an integer and a char which is currently not folded even for little endian target. However this double conversion between host and target memory layout is unelegant and unefficient. I could do just one conversion completely in fold_nonarray_ctor_reference but somehow I feel it is not the right place to do it. As anybody a better advice? Best regards, Thomas Preud'homme