summaryrefslogtreecommitdiff
path: root/src/codegen/struct_layout.rs
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2020-01-12 17:36:29 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2020-01-13 02:33:01 +0100
commit9a2ce1ca6e4dc740fdffa756e962af906e09a2a1 (patch)
tree3607e6f199726267bd1636c9f729921c1d61905a /src/codegen/struct_layout.rs
parentba409edf5d3a1acc6ac4dcb32d1e168cc3a2a41b (diff)
Remove padding for over-aligned structs when we support repr(align).
Before repr(align), we could only safely guarantee up to 8-bytes of alignment (I think the pointer-width check is a more conservative way of doing that, in practice, because I _think_ u64 is 8-byte aligned even for smaller targets). So when we may generate a potentially-under-aligned struct, we always used to pad it so as to guarantee that at least the size (and thus reads from rust for C-allocated structs) was fine. But if we support repr(align), then the above is always unneeded.
Diffstat (limited to 'src/codegen/struct_layout.rs')
-rw-r--r--src/codegen/struct_layout.rs15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs
index 3c03ff11..45e779c9 100644
--- a/src/codegen/struct_layout.rs
+++ b/src/codegen/struct_layout.rs
@@ -258,6 +258,11 @@ impl<'a> StructLayoutTracker<'a> {
}
let padding_bytes = layout.size - self.latest_offset;
+ if padding_bytes == 0 {
+ return None;
+ }
+
+ let repr_align = self.ctx.options().rust_features().repr_align;
// We always pad to get to the correct size if the struct is one of
// those we can't align properly.
@@ -265,12 +270,10 @@ impl<'a> StructLayoutTracker<'a> {
// Note that if the last field we saw was a bitfield, we may need to pad
// regardless, because bitfields don't respect alignment as strictly as
// other fields.
- if padding_bytes > 0 &&
- (padding_bytes >= layout.align ||
- (self.last_field_was_bitfield &&
- padding_bytes >=
- self.latest_field_layout.unwrap().align) ||
- layout.align > self.ctx.target_pointer_size())
+ if padding_bytes >= layout.align ||
+ (self.last_field_was_bitfield &&
+ padding_bytes >= self.latest_field_layout.unwrap().align) ||
+ (!repr_align && layout.align > self.ctx.target_pointer_size())
{
let layout = if self.is_packed {
Layout::new(padding_bytes, 1)