Rollup merge of #121628 - gurry:121534-ice-asymm-binop, r=oli-obk
Do not const prop unions Unions can produce values whose types don't match their underlying layout types which can lead to ICEs on eval. Fixes #121534
This commit is contained in:
commit
218be2771d
@ -585,20 +585,32 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
val.into()
|
||||
}
|
||||
|
||||
Aggregate(ref kind, ref fields) => Value::Aggregate {
|
||||
fields: fields
|
||||
.iter()
|
||||
.map(|field| self.eval_operand(field).map_or(Value::Uninit, Value::Immediate))
|
||||
.collect(),
|
||||
variant: match **kind {
|
||||
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
||||
AggregateKind::Array(_)
|
||||
| AggregateKind::Tuple
|
||||
| AggregateKind::Closure(_, _)
|
||||
| AggregateKind::Coroutine(_, _)
|
||||
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
|
||||
},
|
||||
},
|
||||
Aggregate(ref kind, ref fields) => {
|
||||
// Do not const pop union fields as they can be
|
||||
// made to produce values that don't match their
|
||||
// underlying layout's type (see ICE #121534).
|
||||
// If the last element of the `Adt` tuple
|
||||
// is `Some` it indicates the ADT is a union
|
||||
if let AggregateKind::Adt(_, _, _, _, Some(_)) = **kind {
|
||||
return None;
|
||||
};
|
||||
Value::Aggregate {
|
||||
fields: fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
self.eval_operand(field).map_or(Value::Uninit, Value::Immediate)
|
||||
})
|
||||
.collect(),
|
||||
variant: match **kind {
|
||||
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
||||
AggregateKind::Array(_)
|
||||
| AggregateKind::Tuple
|
||||
| AggregateKind::Closure(_, _)
|
||||
| AggregateKind::Coroutine(_, _)
|
||||
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Repeat(ref op, n) => {
|
||||
trace!(?op, ?n);
|
||||
|
21
tests/ui/lint/ice-unions-known-panics-lint-issue-121534.rs
Normal file
21
tests/ui/lint/ice-unions-known-panics-lint-issue-121534.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Regression test for #121534
|
||||
// Tests that no ICE occurs in KnownPanicsLint when it
|
||||
// evaluates an operation whose operands have different
|
||||
// layout types even though they have the same type.
|
||||
// This situation can be contrived through the use of
|
||||
// unions as in this test
|
||||
|
||||
//@ build-pass
|
||||
union Union {
|
||||
u32_field: u32,
|
||||
i32_field: i32,
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let u32_variant = Union { u32_field: 2 };
|
||||
let i32_variant = Union { i32_field: 3 };
|
||||
let a = unsafe { u32_variant.u32_field };
|
||||
let b = unsafe { i32_variant.u32_field };
|
||||
|
||||
let _diff = a - b;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user