Prohibit const prop of unions in `KnownPanicsLint`

as they have a potential to ICE during layout calculation
This commit is contained in:
Gurinder Singh 2024-04-29 08:16:26 +05:30
parent 6acb9e75eb
commit 254a9fbe86
4 changed files with 64 additions and 24 deletions

View File

@ -896,13 +896,19 @@ impl CanConstProp {
};
for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
let ty = body.local_decls[local].ty;
match tcx.layout_of(param_env.and(ty)) {
Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
// Either the layout fails to compute, then we can't use this local anyway
// or the local is too large, then we don't want to.
_ => {
*val = ConstPropMode::NoPropagation;
continue;
if ty.is_union() {
// Do not const prop unions as they can
// ICE during layout calc
*val = ConstPropMode::NoPropagation;
} else {
match tcx.layout_of(param_env.and(ty)) {
Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
// Either the layout fails to compute, then we can't use this local anyway
// or the local is too large, then we don't want to.
_ => {
*val = ConstPropMode::NoPropagation;
continue;
}
}
}
}

View File

@ -1,17 +0,0 @@
//@ known-bug: #123710
#[repr(packed)]
#[repr(u32)]
enum E {
A,
B,
C,
}
fn main() {
union InvalidTag {
int: u32,
e: E,
}
let _invalid_tag = InvalidTag { int: 4 };
}

View File

@ -0,0 +1,22 @@
// Regression test for issue 123710.
// Tests that the we do not ICE in KnownPanicsLint
// when a union contains an enum with an repr(packed),
// which is a repr not supported for enums
#[repr(packed)]
//~^ ERROR attribute should be applied to a struct or union
#[repr(u32)]
enum E {
A,
B,
C,
}
fn main() {
union InvalidTag {
int: u32,
e: E,
//~^ ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
}
let _invalid_tag = InvalidTag { int: 4 };
}

View File

@ -0,0 +1,29 @@
error[E0517]: attribute should be applied to a struct or union
--> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:6:8
|
LL | #[repr(packed)]
| ^^^^^^
...
LL | / enum E {
LL | | A,
LL | | B,
LL | | C,
LL | | }
| |_- not a struct or union
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
--> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:18:9
|
LL | e: E,
| ^^^^
|
= note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
help: wrap the field type in `ManuallyDrop<...>`
|
LL | e: std::mem::ManuallyDrop<E>,
| +++++++++++++++++++++++ +
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0517, E0740.
For more information about an error, try `rustc --explain E0517`.