diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2020-01-12 17:43:42 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2020-01-13 02:33:01 +0100 |
commit | 7941b9107aa410e23cb172991085f1b1a0e83b07 (patch) | |
tree | da1fe45b37e98d041376553ec74d301e28e5a5d5 | |
parent | 9a2ce1ca6e4dc740fdffa756e962af906e09a2a1 (diff) |
codegen: Max guaranteed alignment is 8 (with u64), not target pointer width.
-rw-r--r-- | src/codegen/struct_layout.rs | 25 | ||||
-rw-r--r-- | tests/expectations/tests/libclang-9/call-conv-field.rs | 15 |
2 files changed, 23 insertions, 17 deletions
diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 45e779c9..6e3f57b2 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -9,6 +9,8 @@ use ir::ty::{Type, TypeKind}; use proc_macro2::{self, Ident, Span}; use std::cmp; +const MAX_GUARANTEED_ALIGN: usize = 8; + /// Trace the layout of struct. #[derive(Debug)] pub struct StructLayoutTracker<'a> { @@ -168,10 +170,10 @@ impl<'a> StructLayoutTracker<'a> { // much we can do about it. if let Some(layout) = self.ctx.resolve_type(inner).layout(self.ctx) { - if layout.align > self.ctx.target_pointer_size() { + if layout.align > MAX_GUARANTEED_ALIGN { field_layout.size = align_to(layout.size, layout.align) * len; - field_layout.align = self.ctx.target_pointer_size(); + field_layout.align = MAX_GUARANTEED_ALIGN; } } } @@ -191,7 +193,7 @@ impl<'a> StructLayoutTracker<'a> { // Otherwise the padding is useless. let need_padding = padding_bytes >= field_layout.align || - field_layout.align > self.ctx.target_pointer_size(); + field_layout.align > MAX_GUARANTEED_ALIGN; self.latest_offset += padding_bytes; @@ -213,10 +215,7 @@ impl<'a> StructLayoutTracker<'a> { if need_padding && padding_bytes != 0 { Some(Layout::new( padding_bytes, - cmp::min( - field_layout.align, - self.ctx.target_pointer_size(), - ), + cmp::min(field_layout.align, MAX_GUARANTEED_ALIGN), )) } else { None @@ -271,14 +270,14 @@ impl<'a> StructLayoutTracker<'a> { // regardless, because bitfields don't respect alignment as strictly as // other fields. 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()) + (self.last_field_was_bitfield && + padding_bytes >= self.latest_field_layout.unwrap().align) || + (!repr_align && layout.align > MAX_GUARANTEED_ALIGN) { let layout = if self.is_packed { Layout::new(padding_bytes, 1) } else if self.last_field_was_bitfield || - layout.align > self.ctx.target_pointer_size() + layout.align > MAX_GUARANTEED_ALIGN { // We've already given up on alignment here. Layout::for_size(self.ctx, padding_bytes) @@ -309,9 +308,9 @@ impl<'a> StructLayoutTracker<'a> { return false; } - // We can only generate up-to a word of alignment unless we support + // We can only generate up-to a 8-bytes of alignment unless we support // repr(align). - repr_align || layout.align <= self.ctx.target_pointer_size() + repr_align || layout.align <= MAX_GUARANTEED_ALIGN } fn padding_bytes(&self, layout: Layout) -> usize { diff --git a/tests/expectations/tests/libclang-9/call-conv-field.rs b/tests/expectations/tests/libclang-9/call-conv-field.rs index 3286ac46..ea7c0e40 100644 --- a/tests/expectations/tests/libclang-9/call-conv-field.rs +++ b/tests/expectations/tests/libclang-9/call-conv-field.rs @@ -12,9 +12,10 @@ #[derive(Default, Copy, Clone)] pub struct JNINativeInterface_ { pub GetVersion: ::std::option::Option< - unsafe extern "stdcall" fn(env: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, + unsafe extern "stdcall" fn( + env: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, >, - pub __bindgen_padding_0: u32, pub __hack: ::std::os::raw::c_ulonglong, } #[test] @@ -30,7 +31,10 @@ fn bindgen_test_layout_JNINativeInterface_() { concat!("Alignment of ", stringify!(JNINativeInterface_)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<JNINativeInterface_>())).GetVersion as *const _ as usize }, + unsafe { + &(*(::std::ptr::null::<JNINativeInterface_>())).GetVersion + as *const _ as usize + }, 0usize, concat!( "Offset of field: ", @@ -40,7 +44,10 @@ fn bindgen_test_layout_JNINativeInterface_() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<JNINativeInterface_>())).__hack as *const _ as usize }, + unsafe { + &(*(::std::ptr::null::<JNINativeInterface_>())).__hack as *const _ + as usize + }, 8usize, concat!( "Offset of field: ", |