diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2020-01-12 17:36:29 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2020-01-13 02:33:01 +0100 |
commit | 9a2ce1ca6e4dc740fdffa756e962af906e09a2a1 (patch) | |
tree | 3607e6f199726267bd1636c9f729921c1d61905a /src/codegen/struct_layout.rs | |
parent | ba409edf5d3a1acc6ac4dcb32d1e168cc3a2a41b (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.rs | 15 |
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) |