Skip to content

Commit 473cfc2

Browse files
committed
codegen: Use target pointer size consistently for layout calculations.
Closes #1284
1 parent 96bba97 commit 473cfc2

File tree

4 files changed

+36
-47
lines changed

4 files changed

+36
-47
lines changed

src/codegen/mod.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ use std::collections::{HashSet, VecDeque};
4545
use std::collections::hash_map::{Entry, HashMap};
4646
use std::fmt::Write;
4747
use std::iter;
48-
use std::mem;
4948
use std::ops;
5049

5150
// Name of type defined in constified enum module
@@ -1777,7 +1776,7 @@ impl CodeGenerator for CompInfo {
17771776
let align = layout.align;
17781777

17791778
let check_struct_align =
1780-
if align > mem::size_of::<*mut ()>() {
1779+
if align > ctx.target_pointer_size() {
17811780
// FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
17821781
None
17831782
} else {
@@ -2720,9 +2719,8 @@ trait TryToOpaque {
27202719
/// leverage the blanket impl for this trait.
27212720
trait ToOpaque: TryToOpaque {
27222721
fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout {
2723-
self.try_get_layout(ctx, extra).unwrap_or_else(
2724-
|_| Layout::for_size(1),
2725-
)
2722+
self.try_get_layout(ctx, extra)
2723+
.unwrap_or_else(|_| Layout::for_size(ctx, 1))
27262724
}
27272725

27282726
fn to_opaque(

src/codegen/struct_layout.rs

+14-17
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use ir::layout::Layout;
88
use ir::ty::{Type, TypeKind};
99
use quote;
1010
use std::cmp;
11-
use std::mem;
1211

1312
/// Trace the layout of struct.
1413
#[derive(Debug)]
@@ -101,7 +100,7 @@ impl<'a> StructLayoutTracker<'a> {
101100
pub fn saw_vtable(&mut self) {
102101
debug!("saw vtable for {}", self.name);
103102

104-
let ptr_size = mem::size_of::<*mut ()>();
103+
let ptr_size = self.ctx.target_pointer_size();
105104
self.latest_offset += ptr_size;
106105
self.latest_field_layout = Some(Layout::new(ptr_size, ptr_size));
107106
self.max_field_align = ptr_size;
@@ -165,15 +164,13 @@ impl<'a> StructLayoutTracker<'a> {
165164
// can support.
166165
//
167166
// This means that the structs in the array are super-unsafe to
168-
// access, since they won't be properly aligned, but *shrug*.
169-
if let Some(layout) = self.ctx.resolve_type(inner).layout(
170-
self.ctx,
171-
)
172-
{
173-
if layout.align > mem::size_of::<*mut ()>() {
174-
field_layout.size = align_to(layout.size, layout.align) *
175-
len;
176-
field_layout.align = mem::size_of::<*mut ()>();
167+
// access, since they won't be properly aligned, but there's not too
168+
// much we can do about it.
169+
if let Some(layout) = self.ctx.resolve_type(inner).layout(self.ctx) {
170+
if layout.align > self.ctx.target_pointer_size() {
171+
field_layout.size =
172+
align_to(layout.size, layout.align) * len;
173+
field_layout.align = self.ctx.target_pointer_size();
177174
}
178175
}
179176
}
@@ -193,7 +190,7 @@ impl<'a> StructLayoutTracker<'a> {
193190

194191
// Otherwise the padding is useless.
195192
let need_padding = padding_bytes >= field_layout.align ||
196-
field_layout.align > mem::size_of::<*mut ()>();
193+
field_layout.align > self.ctx.target_pointer_size();
197194

198195
self.latest_offset += padding_bytes;
199196

@@ -215,7 +212,7 @@ impl<'a> StructLayoutTracker<'a> {
215212
if need_padding && padding_bytes != 0 {
216213
Some(Layout::new(
217214
padding_bytes,
218-
cmp::min(field_layout.align, mem::size_of::<*mut ()>()),
215+
cmp::min(field_layout.align, self.ctx.target_pointer_size())
219216
))
220217
} else {
221218
None
@@ -267,15 +264,15 @@ impl<'a> StructLayoutTracker<'a> {
267264
(self.last_field_was_bitfield &&
268265
padding_bytes >=
269266
self.latest_field_layout.unwrap().align) ||
270-
layout.align > mem::size_of::<*mut ()>())
267+
layout.align > self.ctx.target_pointer_size())
271268
{
272269
let layout = if self.is_packed {
273270
Layout::new(padding_bytes, 1)
274271
} else if self.last_field_was_bitfield ||
275-
layout.align > mem::size_of::<*mut ()>()
272+
layout.align > self.ctx.target_pointer_size()
276273
{
277274
// We've already given up on alignment here.
278-
Layout::for_size(padding_bytes)
275+
Layout::for_size(self.ctx, padding_bytes)
279276
} else {
280277
Layout::new(padding_bytes, layout.align)
281278
};
@@ -290,7 +287,7 @@ impl<'a> StructLayoutTracker<'a> {
290287

291288
pub fn requires_explicit_align(&self, layout: Layout) -> bool {
292289
self.max_field_align < layout.align &&
293-
layout.align <= mem::size_of::<*mut ()>()
290+
layout.align <= self.ctx.target_pointer_size()
294291
}
295292

296293
fn padding_bytes(&self, layout: Layout) -> usize {

src/ir/layout.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
44
CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
55
CanTriviallyDerivePartialEqOrPartialOrd, CanDerive};
66
use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
7+
use ir::context::BindgenContext;
78
use clang;
8-
use std::{cmp, mem};
9+
use std::cmp;
910

1011
/// A type that represents the struct layout of a type.
1112
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -20,10 +21,15 @@ pub struct Layout {
2021

2122
#[test]
2223
fn test_layout_for_size() {
24+
use std::mem;
25+
2326
let ptr_size = mem::size_of::<*mut ()>();
24-
assert_eq!(Layout::for_size(ptr_size), Layout::new(ptr_size, ptr_size));
2527
assert_eq!(
26-
Layout::for_size(3 * ptr_size),
28+
Layout::for_size_internal(ptr_size, ptr_size),
29+
Layout::new(ptr_size, ptr_size)
30+
);
31+
assert_eq!(
32+
Layout::for_size_internal(ptr_size, 3 * ptr_size),
2733
Layout::new(3 * ptr_size, ptr_size)
2834
);
2935
}
@@ -39,13 +45,9 @@ impl Layout {
3945
}
4046
}
4147

42-
/// Creates a non-packed layout for a given size, trying to use the maximum
43-
/// alignment possible.
44-
pub fn for_size(size: usize) -> Self {
48+
fn for_size_internal(ptr_size: usize, size: usize) -> Self {
4549
let mut next_align = 2;
46-
while size % next_align == 0 &&
47-
next_align <= mem::size_of::<*mut ()>()
48-
{
50+
while size % next_align == 0 && next_align <= ptr_size {
4951
next_align *= 2;
5052
}
5153
Layout {
@@ -55,6 +57,12 @@ impl Layout {
5557
}
5658
}
5759

60+
/// Creates a non-packed layout for a given size, trying to use the maximum
61+
/// alignment possible.
62+
pub fn for_size(ctx: &BindgenContext, size: usize) -> Self {
63+
Self::for_size_internal(ctx.target_pointer_size(), size)
64+
}
65+
5866
/// Is this a zero-sized layout?
5967
pub fn is_zero(&self) -> bool {
6068
self.size == 0 && self.align == 0

src/ir/ty.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use clang::{self, Cursor};
1616
use parse::{ClangItemParser, ParseError, ParseResult};
1717
use std::borrow::Cow;
1818
use std::io;
19-
use std::mem;
2019

2120
/// The base representation of a type in bindgen.
2221
///
@@ -232,8 +231,6 @@ impl Type {
232231

233232
/// What is the layout of this type?
234233
pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
235-
use std::mem;
236-
237234
self.layout.or_else(|| {
238235
match self.kind {
239236
TypeKind::Comp(ref ci) => ci.layout(ctx),
@@ -242,8 +239,8 @@ impl Type {
242239
TypeKind::Pointer(..) |
243240
TypeKind::BlockPointer => {
244241
Some(Layout::new(
245-
mem::size_of::<*mut ()>(),
246-
mem::align_of::<*mut ()>(),
242+
ctx.target_pointer_size(),
243+
ctx.target_pointer_size(),
247244
))
248245
}
249246
TypeKind::ResolvedTypeRef(inner) => {
@@ -596,17 +593,6 @@ pub enum FloatKind {
596593
Float128,
597594
}
598595

599-
impl FloatKind {
600-
/// If this type has a known size, return it (in bytes).
601-
pub fn known_size(&self) -> usize {
602-
match *self {
603-
FloatKind::Float => mem::size_of::<f32>(),
604-
FloatKind::Double | FloatKind::LongDouble => mem::size_of::<f64>(),
605-
FloatKind::Float128 => mem::size_of::<f64>() * 2,
606-
}
607-
}
608-
}
609-
610596
/// The different kinds of types that we can parse.
611597
#[derive(Debug)]
612598
pub enum TypeKind {

0 commit comments

Comments
 (0)