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
This commit is contained in:
Emilio Cobos Álvarez
2018-03-31 15:30:19 +02:00
parent 974c1b0777
commit 4e51c59dd6
4 changed files with 215 additions and 4 deletions
+3 -2
View File
@@ -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! {
+12 -2
View File
@@ -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 {
+179
View File
@@ -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)
)
);
}
+21
View File
@@ -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;
};