diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-03-31 15:30:19 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-04-03 11:27:46 +0200 |
commit | fa1245198a0c61c13c0a8e6e02d431efe25ba0c9 (patch) | |
tree | 6a098f2e0e30bbc2ba703ee13183764b28758251 | |
parent | 473cfc29ff0b5a6a8f268d8a3069ffe9502edf90 (diff) |
codegen: Don't skip alignment checks if we support repr align.
Plus fix the check that avoids us generating explicit alignment fields for
structs aligned to more than pointer-size.
Fixes #1291
-rw-r--r-- | src/codegen/mod.rs | 5 | ||||
-rw-r--r-- | src/codegen/struct_layout.rs | 14 | ||||
-rw-r--r-- | tests/expectations/tests/issue-1291.rs | 179 | ||||
-rw-r--r-- | tests/headers/issue-1291.hpp | 21 |
4 files changed, 215 insertions, 4 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 5411b2a0..39babb6b 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1776,8 +1776,9 @@ impl CodeGenerator for CompInfo { let align = layout.align; let check_struct_align = - if align > ctx.target_pointer_size() { - // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready + if align > ctx.target_pointer_size() && + !ctx.options().rust_features().repr_align + { None } else { Some(quote! { diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index d2be5aff..3a641f4a 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -286,8 +286,18 @@ impl<'a> StructLayoutTracker<'a> { } pub fn requires_explicit_align(&self, layout: Layout) -> bool { - self.max_field_align < layout.align && - layout.align <= self.ctx.target_pointer_size() + 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() } fn padding_bytes(&self, layout: Layout) -> usize { diff --git a/tests/expectations/tests/issue-1291.rs b/tests/expectations/tests/issue-1291.rs new file mode 100644 index 00000000..a2330541 --- /dev/null +++ b/tests/expectations/tests/issue-1291.rs @@ -0,0 +1,179 @@ +/* automatically generated by rust-bindgen */ + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Default, Copy, Clone)] +pub struct RTCRay { + pub org: [f32; 3usize], + pub align0: f32, + pub dir: [f32; 3usize], + pub align1: f32, + pub tnear: f32, + pub tfar: f32, + pub time: f32, + pub mask: ::std::os::raw::c_uint, + pub Ng: [f32; 3usize], + pub align2: f32, + pub u: f32, + pub v: f32, + pub geomID: ::std::os::raw::c_uint, + pub primID: ::std::os::raw::c_uint, + pub instID: ::std::os::raw::c_uint, + pub __bindgen_padding_0: [u32; 3usize], + pub __bindgen_align: [u8; 0usize], +} +#[test] +fn bindgen_test_layout_RTCRay() { + assert_eq!( + ::std::mem::size_of::<RTCRay>(), + 96usize, + concat!("Size of: ", stringify!(RTCRay)) + ); + assert_eq!( + ::std::mem::align_of::<RTCRay>(), + 16usize, + concat!("Alignment of ", stringify!(RTCRay)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).org as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(org) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).align0 as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(align0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).dir as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(dir) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).align1 as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(align1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).tnear as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(tnear) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).tfar as *const _ as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(tfar) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).time as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).mask as *const _ as usize }, + 44usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(mask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).Ng as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(Ng) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).align2 as *const _ as usize }, + 60usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(align2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).u as *const _ as usize }, + 64usize, + concat!("Offset of field: ", stringify!(RTCRay), "::", stringify!(u)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).v as *const _ as usize }, + 68usize, + concat!("Offset of field: ", stringify!(RTCRay), "::", stringify!(v)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).geomID as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(geomID) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).primID as *const _ as usize }, + 76usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(primID) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<RTCRay>())).instID as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(RTCRay), + "::", + stringify!(instID) + ) + ); +} diff --git a/tests/headers/issue-1291.hpp b/tests/headers/issue-1291.hpp new file mode 100644 index 00000000..4ec524f1 --- /dev/null +++ b/tests/headers/issue-1291.hpp @@ -0,0 +1,21 @@ +// bindgen-flags: --rust-target 1.25 +// bindgen-unstable + +struct __attribute__((aligned(16))) RTCRay + { + float org[3]; + float align0; + float dir[3]; + float align1; + float tnear; + float tfar; + float time; + unsigned mask; + float Ng[3]; + float align2; + float u; + float v; + unsigned geomID; + unsigned primID; + unsigned instID; +}; |