Skip to content

Commit eff06cc

Browse files
committed
WIP issue rust-lang#1076
1 parent 1cb1101 commit eff06cc

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

src/codegen/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1189,16 +1189,18 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
11891189
};
11901190
fields.extend(Some(field));
11911191

1192+
let field_int_align = self.layout().align;
11921193
let mut field_int_size = self.layout().size;
11931194
if !field_int_size.is_power_of_two() {
11941195
field_int_size = field_int_size.next_power_of_two();
11951196
}
11961197

11971198
let unit_field_int_ty = match field_int_size {
1199+
1 => quote! { u8 },
1200+
n if field_int_align == 1 => quote! { [u8; #n] },
11981201
8 => quote! { u64 },
11991202
4 => quote! { u32 },
12001203
2 => quote! { u16 },
1201-
1 => quote! { u8 },
12021204
size => {
12031205
debug_assert!(size > 8);
12041206
// Can't generate bitfield accessors for unit sizes larget than

src/ir/comp.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,13 @@ fn bitfields_to_allocation_units<E, I>(
574574
.layout(ctx)
575575
.expect("Bitfield without layout? Gah!");
576576
let bitfield_size = bitfield_layout.size;
577-
let bitfield_align = bitfield_layout.align;
577+
let bitfield_align = if bitfield.name().is_none() {
578+
// Anonymous bitfields can never be read, so unaligned reads are not
579+
// a worry, and they don't contribute to alignement.
580+
1
581+
} else {
582+
bitfield_layout.align
583+
};
578584

579585
let mut offset = unit_size_in_bits;
580586
if is_ms_struct {
@@ -612,20 +618,22 @@ fn bitfields_to_allocation_units<E, I>(
612618
}
613619
}
614620

621+
max_align = cmp::max(max_align, bitfield_align);
622+
623+
// NB: The `bitfield_width` here is completely, absolutely intentional.
624+
// Alignment of the allocation unit is based on the maximum bitfield
625+
// width, not (directly) on the bitfields' types' alignment.
626+
if bitfield.name().is_some() {
627+
unit_align = cmp::max(unit_align, bitfield_width);
628+
}
629+
615630
// Always keep all bitfields around. While unnamed bitifields are used
616631
// for padding (and usually not needed hereafter), large unnamed
617632
// bitfields over their types size cause weird allocation size behavior from clang.
618633
// Therefore, all bitfields needed to be kept around in order to check for this
619634
// and make the struct opaque in this case
620635
bitfields_in_unit.push(Bitfield::new(offset, bitfield));
621636

622-
max_align = cmp::max(max_align, bitfield_align);
623-
624-
// NB: The `bitfield_width` here is completely, absolutely intentional.
625-
// Alignment of the allocation unit is based on the maximum bitfield
626-
// width, not (directly) on the bitfields' types' alignment.
627-
unit_align = cmp::max(unit_align, bitfield_width);
628-
629637
unit_size_in_bits = offset + bitfield_width;
630638

631639
// Compute what the physical unit's final size would be given what we
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Because anonymous bitfields can't be read, we don't need to worry about
3+
* unaligned reads, and therefore they don't contribute to alignment.
4+
*/
5+
struct S1 {
6+
signed : 15;
7+
unsigned : 6
8+
};

0 commit comments

Comments
 (0)