summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/comp.rs22
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