Skip to content

Commit 087f1c2

Browse files
committed
rustc: ensure optimized enums have a properly aligned size.
1 parent a3a7203 commit 087f1c2

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

src/librustc/ty/layout.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ impl<'a, 'tcx> LayoutDetails {
14921492
}).collect::<Result<Vec<_>, _>>()?;
14931493

14941494
let offset = st[i].fields.offset(field_index) + offset;
1495-
let LayoutDetails { size, mut align, .. } = st[i];
1495+
let LayoutDetails { mut size, mut align, .. } = st[i];
14961496

14971497
let mut niche_align = niche.value.align(dl);
14981498
let abi = if offset.bytes() == 0 && niche.value.size(dl) == size {
@@ -1504,6 +1504,7 @@ impl<'a, 'tcx> LayoutDetails {
15041504
Abi::Aggregate { sized: true }
15051505
};
15061506
align = align.max(niche_align);
1507+
size = size.abi_align(align);
15071508

15081509
return Ok(tcx.intern_layout(LayoutDetails {
15091510
variants: Variants::NicheFilling {

src/test/run-pass/packed-struct-optimized-enum.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@ impl<T: Copy> Clone for Packed<T> {
1616
fn clone(&self) -> Self { *self }
1717
}
1818

19-
fn main() {
20-
let one = (Some(Packed((&(), 0))), true);
19+
fn sanity_check_size<T: Copy>(one: T) {
2120
let two = [one, one];
2221
let stride = (&two[1] as *const _ as usize) - (&two[0] as *const _ as usize);
22+
assert_eq!(stride, std::mem::size_of_val(&one));
23+
}
2324

25+
fn main() {
2426
// This can fail if rustc and LLVM disagree on the size of a type.
2527
// In this case, `Option<Packed<(&(), u32)>>` was erronously not
2628
// marked as packed despite needing alignment `1` and containing
2729
// its `&()` discriminant, which has alignment larger than `1`.
28-
assert_eq!(stride, std::mem::size_of_val(&one));
30+
sanity_check_size((Some(Packed((&(), 0))), true));
31+
32+
// In #46769, `Option<(Packed<&()>, bool)>` was found to have
33+
// pointer alignment, without actually being aligned in size.
34+
// E.g. on 64-bit platforms, it had alignment `8` but size `9`.
35+
sanity_check_size(Some((Packed(&()), true)));
2936
}

0 commit comments

Comments
 (0)