summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-03-31 15:30:19 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-04-03 11:27:46 +0200
commitfa1245198a0c61c13c0a8e6e02d431efe25ba0c9 (patch)
tree6a098f2e0e30bbc2ba703ee13183764b28758251
parent473cfc29ff0b5a6a8f268d8a3069ffe9502edf90 (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.rs5
-rw-r--r--src/codegen/struct_layout.rs14
-rw-r--r--tests/expectations/tests/issue-1291.rs179
-rw-r--r--tests/headers/issue-1291.hpp21
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;
+};