diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index b70fb658bc..0ea23ddf4d 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -287,18 +287,23 @@ impl<'a> StructLayoutTracker<'a> { } pub fn requires_explicit_align(&self, layout: Layout) -> bool { + let repr_align = self.ctx.options().rust_features().repr_align; + + // Always force explicit repr(align) for stuff more than 16-byte aligned + // to work-around https://github.com/rust-lang/rust/issues/54341. + // + // Worst-case this just generates redundant alignment attributes. + if repr_align && self.max_field_align >= 16 { + return true; + } + if self.max_field_align >= layout.align { return false; } - // At this point we require explicit alignment, but we may not be able - // to generate the right bits, let's double check. - if self.ctx.options().rust_features().repr_align { - return true; - } // We can only generate up-to a word of alignment unless we support // repr(align). - layout.align <= self.ctx.target_pointer_size() + repr_align || layout.align <= self.ctx.target_pointer_size() } fn padding_bytes(&self, layout: Layout) -> usize { diff --git a/tests/expectations/tests/i128.rs b/tests/expectations/tests/i128.rs index cd91f141d7..1fae2bee8c 100644 --- a/tests/expectations/tests/i128.rs +++ b/tests/expectations/tests/i128.rs @@ -8,6 +8,7 @@ )] #[repr(C)] +#[repr(align(16))] #[derive(Debug, Default, Copy, Clone)] pub struct foo { pub my_signed: i128, diff --git a/tests/expectations/tests/long_double.rs b/tests/expectations/tests/long_double.rs index 05d56414ac..632eeb5a69 100644 --- a/tests/expectations/tests/long_double.rs +++ b/tests/expectations/tests/long_double.rs @@ -8,6 +8,7 @@ )] #[repr(C)] +#[repr(align(16))] #[derive(Debug, Default, Copy, Clone)] pub struct foo { pub bar: u128,