summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2020-01-12 17:43:42 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2020-01-13 02:33:01 +0100
commit7941b9107aa410e23cb172991085f1b1a0e83b07 (patch)
treeda1fe45b37e98d041376553ec74d301e28e5a5d5
parent9a2ce1ca6e4dc740fdffa756e962af906e09a2a1 (diff)
codegen: Max guaranteed alignment is 8 (with u64), not target pointer width.
-rw-r--r--src/codegen/struct_layout.rs25
-rw-r--r--tests/expectations/tests/libclang-9/call-conv-field.rs15
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: ",