diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-04-03 05:28:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-03 05:28:52 -0400 |
commit | 0166f4a1b2a9a65df51767be64a6796742588023 (patch) | |
tree | e3dd094fc497b48c88f5de8393bb03e73538667f /src/codegen/struct_layout.rs | |
parent | 5b8572fb567eaadb3f424b502f823262b8002816 (diff) | |
parent | de0d850dac259070a5988d5709cd7217fddc32b7 (diff) |
Auto merge of #1289 - emilio:target-stuff, r=fitzgen
codegen: Use target pointer size consistently for layout calculations
Assuming new enough libclang, this PR makes cross-compilation do layout calculations properly.
Fixes #1284
Diffstat (limited to 'src/codegen/struct_layout.rs')
-rw-r--r-- | src/codegen/struct_layout.rs | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index a538c35f..3a641f4a 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -8,7 +8,6 @@ use ir::layout::Layout; use ir::ty::{Type, TypeKind}; use quote; use std::cmp; -use std::mem; /// Trace the layout of struct. #[derive(Debug)] @@ -101,7 +100,7 @@ impl<'a> StructLayoutTracker<'a> { pub fn saw_vtable(&mut self) { debug!("saw vtable for {}", self.name); - let ptr_size = mem::size_of::<*mut ()>(); + let ptr_size = self.ctx.target_pointer_size(); self.latest_offset += ptr_size; self.latest_field_layout = Some(Layout::new(ptr_size, ptr_size)); self.max_field_align = ptr_size; @@ -165,15 +164,13 @@ impl<'a> StructLayoutTracker<'a> { // can support. // // This means that the structs in the array are super-unsafe to - // access, since they won't be properly aligned, but *shrug*. - if let Some(layout) = self.ctx.resolve_type(inner).layout( - self.ctx, - ) - { - if layout.align > mem::size_of::<*mut ()>() { - field_layout.size = align_to(layout.size, layout.align) * - len; - field_layout.align = mem::size_of::<*mut ()>(); + // access, since they won't be properly aligned, but there's not too + // 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() { + field_layout.size = + align_to(layout.size, layout.align) * len; + field_layout.align = self.ctx.target_pointer_size(); } } } @@ -193,7 +190,7 @@ impl<'a> StructLayoutTracker<'a> { // Otherwise the padding is useless. let need_padding = padding_bytes >= field_layout.align || - field_layout.align > mem::size_of::<*mut ()>(); + field_layout.align > self.ctx.target_pointer_size(); self.latest_offset += padding_bytes; @@ -215,7 +212,7 @@ impl<'a> StructLayoutTracker<'a> { if need_padding && padding_bytes != 0 { Some(Layout::new( padding_bytes, - cmp::min(field_layout.align, mem::size_of::<*mut ()>()), + cmp::min(field_layout.align, self.ctx.target_pointer_size()) )) } else { None @@ -267,15 +264,15 @@ impl<'a> StructLayoutTracker<'a> { (self.last_field_was_bitfield && padding_bytes >= self.latest_field_layout.unwrap().align) || - layout.align > mem::size_of::<*mut ()>()) + layout.align > self.ctx.target_pointer_size()) { let layout = if self.is_packed { Layout::new(padding_bytes, 1) } else if self.last_field_was_bitfield || - layout.align > mem::size_of::<*mut ()>() + layout.align > self.ctx.target_pointer_size() { // We've already given up on alignment here. - Layout::for_size(padding_bytes) + Layout::for_size(self.ctx, padding_bytes) } else { Layout::new(padding_bytes, layout.align) }; @@ -289,8 +286,18 @@ impl<'a> StructLayoutTracker<'a> { } pub fn requires_explicit_align(&self, layout: Layout) -> bool { - self.max_field_align < layout.align && - layout.align <= mem::size_of::<*mut ()>() + 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 { |