diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/comp.rs | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs index f3c986e7..7265660c 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -608,6 +608,21 @@ fn bitfields_to_allocation_units<E, I>( } } + // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not + // affect the alignment of a structure or union". This makes sense: such + // bit-fields are only used for padding, and we can't perform an + // un-aligned read of something we can't read because we can't even name + // it. + if bitfield.name().is_some() { + max_align = cmp::max(max_align, bitfield_align); + + // NB: The `bitfield_width` here is completely, absolutely + // intentional. Alignment of the allocation unit is based on the + // maximum bitfield width, not (directly) on the bitfields' types' + // alignment. + unit_align = cmp::max(unit_align, bitfield_width); + } + // Always keep all bitfields around. While unnamed bitifields are used // for padding (and usually not needed hereafter), large unnamed // bitfields over their types size cause weird allocation size behavior from clang. @@ -615,13 +630,6 @@ fn bitfields_to_allocation_units<E, I>( // and make the struct opaque in this case bitfields_in_unit.push(Bitfield::new(offset, bitfield)); - max_align = cmp::max(max_align, bitfield_align); - - // NB: The `bitfield_width` here is completely, absolutely intentional. - // Alignment of the allocation unit is based on the maximum bitfield - // width, not (directly) on the bitfields' types' alignment. - unit_align = cmp::max(unit_align, bitfield_width); - unit_size_in_bits = offset + bitfield_width; // Compute what the physical unit's final size would be given what we |