fix the layout of repr(align) enums
This commit is contained in:
parent
54f79babae
commit
cedc428a5f
4 changed files with 203 additions and 4 deletions
|
@ -1418,9 +1418,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
|||
|
||||
if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
|
||||
abi = Abi::Uninhabited;
|
||||
} else if tag.size(dl) == size || variants.iter().all(|layout| layout.is_empty()) {
|
||||
// Without latter check aligned enums with custom discriminant values
|
||||
// Would result in ICE see the issue #92464 for more info
|
||||
} else if tag.size(dl) == size {
|
||||
// Make sure we only use scalar layout when the enum is entirely its
|
||||
// own tag (i.e. it has no padding nor any non-ZST variant fields).
|
||||
abi = Abi::Scalar(tag);
|
||||
} else {
|
||||
// Try to use a ScalarPair for all tagged enums.
|
||||
|
|
|
@ -11,5 +11,13 @@ enum Aligned {
|
|||
fn main() {
|
||||
let aligned = Aligned::Zero;
|
||||
let fo = aligned as u8;
|
||||
println!("foo {}",fo);
|
||||
println!("foo {}", fo);
|
||||
println!("{}", tou8(Aligned::Zero));
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn tou8(al: Aligned) -> u8 {
|
||||
// Cast behind a function call so ConstProp does not see it
|
||||
// (so that we can test codegen).
|
||||
al as u8
|
||||
}
|
||||
|
|
19
src/test/ui/layout/issue-96185-overaligned-enum.rs
Normal file
19
src/test/ui/layout/issue-96185-overaligned-enum.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN"
|
||||
#![crate_type = "lib"]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// This cannot use `Scalar` abi since there is padding.
|
||||
#[rustc_layout(debug)]
|
||||
#[repr(align(8))]
|
||||
pub enum Aligned1 { //~ ERROR: layout_of
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
}
|
||||
|
||||
// This should use `Scalar` abi.
|
||||
#[rustc_layout(debug)]
|
||||
#[repr(align(1))]
|
||||
pub enum Aligned2 { //~ ERROR: layout_of
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
}
|
172
src/test/ui/layout/issue-96185-overaligned-enum.stderr
Normal file
172
src/test/ui/layout/issue-96185-overaligned-enum.stderr
Normal file
|
@ -0,0 +1,172 @@
|
|||
error: layout_of(Aligned1) = Layout {
|
||||
fields: Arbitrary {
|
||||
offsets: [
|
||||
Size(0 bytes),
|
||||
],
|
||||
memory_index: [
|
||||
0,
|
||||
],
|
||||
},
|
||||
variants: Multiple {
|
||||
tag: Initialized {
|
||||
value: Int(
|
||||
I8,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
},
|
||||
tag_encoding: Direct,
|
||||
tag_field: 0,
|
||||
variants: [
|
||||
Layout {
|
||||
fields: Arbitrary {
|
||||
offsets: [],
|
||||
memory_index: [],
|
||||
},
|
||||
variants: Single {
|
||||
index: 0,
|
||||
},
|
||||
abi: Aggregate {
|
||||
sized: true,
|
||||
},
|
||||
largest_niche: None,
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(8 bytes),
|
||||
pref: $PREF_ALIGN,
|
||||
},
|
||||
size: Size(8 bytes),
|
||||
},
|
||||
Layout {
|
||||
fields: Arbitrary {
|
||||
offsets: [],
|
||||
memory_index: [],
|
||||
},
|
||||
variants: Single {
|
||||
index: 1,
|
||||
},
|
||||
abi: Aggregate {
|
||||
sized: true,
|
||||
},
|
||||
largest_niche: None,
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(8 bytes),
|
||||
pref: $PREF_ALIGN,
|
||||
},
|
||||
size: Size(8 bytes),
|
||||
},
|
||||
],
|
||||
},
|
||||
abi: Aggregate {
|
||||
sized: true,
|
||||
},
|
||||
largest_niche: Some(
|
||||
Niche {
|
||||
offset: Size(0 bytes),
|
||||
value: Int(
|
||||
I8,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
},
|
||||
),
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(8 bytes),
|
||||
pref: $PREF_ALIGN,
|
||||
},
|
||||
size: Size(8 bytes),
|
||||
}
|
||||
--> $DIR/issue-96185-overaligned-enum.rs:8:1
|
||||
|
|
||||
LL | pub enum Aligned1 {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: layout_of(Aligned2) = Layout {
|
||||
fields: Arbitrary {
|
||||
offsets: [
|
||||
Size(0 bytes),
|
||||
],
|
||||
memory_index: [
|
||||
0,
|
||||
],
|
||||
},
|
||||
variants: Multiple {
|
||||
tag: Initialized {
|
||||
value: Int(
|
||||
I8,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
},
|
||||
tag_encoding: Direct,
|
||||
tag_field: 0,
|
||||
variants: [
|
||||
Layout {
|
||||
fields: Arbitrary {
|
||||
offsets: [],
|
||||
memory_index: [],
|
||||
},
|
||||
variants: Single {
|
||||
index: 0,
|
||||
},
|
||||
abi: Aggregate {
|
||||
sized: true,
|
||||
},
|
||||
largest_niche: None,
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(1 bytes),
|
||||
pref: $PREF_ALIGN,
|
||||
},
|
||||
size: Size(1 bytes),
|
||||
},
|
||||
Layout {
|
||||
fields: Arbitrary {
|
||||
offsets: [],
|
||||
memory_index: [],
|
||||
},
|
||||
variants: Single {
|
||||
index: 1,
|
||||
},
|
||||
abi: Aggregate {
|
||||
sized: true,
|
||||
},
|
||||
largest_niche: None,
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(1 bytes),
|
||||
pref: $PREF_ALIGN,
|
||||
},
|
||||
size: Size(1 bytes),
|
||||
},
|
||||
],
|
||||
},
|
||||
abi: Scalar(
|
||||
Initialized {
|
||||
value: Int(
|
||||
I8,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
},
|
||||
),
|
||||
largest_niche: Some(
|
||||
Niche {
|
||||
offset: Size(0 bytes),
|
||||
value: Int(
|
||||
I8,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
},
|
||||
),
|
||||
align: AbiAndPrefAlign {
|
||||
abi: Align(1 bytes),
|
||||
pref: $PREF_ALIGN,
|
||||
},
|
||||
size: Size(1 bytes),
|
||||
}
|
||||
--> $DIR/issue-96185-overaligned-enum.rs:16:1
|
||||
|
|
||||
LL | pub enum Aligned2 {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Add table
Reference in a new issue