Skip to content

Commit bbc4a74

Browse files
committed
rt: Fix shape alignment of 64-bit ints on x86. Issue #2303
1 parent 8e15640 commit bbc4a74

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/rt/rust_shape.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ rust_alignof<double>() {
123123
return 4;
124124
}
125125

126+
// Issue #2303
127+
// On 32-bit x86 the alignment of 64-bit ints in structures is 4 bytes
128+
// Which is different from the preferred 8-byte alignment reported
129+
// by __alignof__ (at least on gcc).
130+
#ifdef __i386__
131+
template<>
132+
inline size_t
133+
rust_alignof<uint64_t>() {
134+
return 4;
135+
}
136+
#endif
137+
126138

127139
// Utility classes
128140

src/test/run-pass/rec-align-32-bit.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// xfail-pretty
2+
// Issue #2303
3+
4+
// This is the type with the questionable alignment
5+
type inner = {
6+
c64: u64
7+
};
8+
9+
// This is the type that contains the type with the
10+
// questionable alignment, for testing
11+
type outer = {
12+
c8: u8,
13+
t: inner
14+
};
15+
16+
#[cfg(target_arch = "x86")]
17+
fn main() {
18+
19+
let x = {c8: 22u8, t: {c64: 44u64}};
20+
21+
// Send it through the shape code
22+
let y = #fmt["%?", x];
23+
24+
#debug("align inner = %?", sys::align_of::<inner>()); // 8
25+
#debug("size outer = %?", sys::size_of::<outer>()); // 12
26+
#debug("y = %s", y); // (22, (0))
27+
28+
// per clang/gcc the alignment of `inner` is 4 on x86.
29+
// we say it's 8
30+
//assert sys::align_of::<inner>() == 4u; // fails
31+
32+
// per clang/gcc the size of `outer` should be 12
33+
// because `inner`s alignment was 4.
34+
// LLVM packs the struct the way clang likes, despite
35+
// our intents regarding the alignment of `inner` and
36+
// we end up with the same size `outer` as clang
37+
assert sys::size_of::<outer>() == 12u; // passes
38+
39+
// But now our shape code doesn't find the inner struct
40+
// We print (22, (0))
41+
assert y == "(22, (44))"; // fails
42+
}
43+
44+
#[cfg(target_arch = "x86_64")]
45+
fn main() { }

0 commit comments

Comments
 (0)