Prohibit const prop of unions in KnownPanicsLint
as they have a potential to ICE during layout calculation
This commit is contained in:
parent
6acb9e75eb
commit
254a9fbe86
@ -896,13 +896,19 @@ pub fn check<'tcx>(
|
||||
};
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 };
|
||||
}
|
@ -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 };
|
||||
}
|
@ -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`.
|
Loading…
Reference in New Issue
Block a user