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
4 changed files with 64 additions and 24 deletions
|
@ -896,13 +896,19 @@ impl CanConstProp {
|
||||||
};
|
};
|
||||||
for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
|
for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
|
||||||
let ty = body.local_decls[local].ty;
|
let ty = body.local_decls[local].ty;
|
||||||
match tcx.layout_of(param_env.and(ty)) {
|
if ty.is_union() {
|
||||||
Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
|
// Do not const prop unions as they can
|
||||||
// Either the layout fails to compute, then we can't use this local anyway
|
// ICE during layout calc
|
||||||
// or the local is too large, then we don't want to.
|
*val = ConstPropMode::NoPropagation;
|
||||||
_ => {
|
} else {
|
||||||
*val = ConstPropMode::NoPropagation;
|
match tcx.layout_of(param_env.and(ty)) {
|
||||||
continue;
|
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…
Add table
Add a link
Reference in a new issue