Skip to content

Commit

Permalink
Rollup merge of #121628 - gurry:121534-ice-asymm-binop, r=oli-obk
Browse files Browse the repository at this point in the history
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
  • Loading branch information
matthiaskrgr authored Feb 26, 2024
2 parents 4f167b4 + 633c92c commit 218be27
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
40 changes: 26 additions & 14 deletions compiler/rustc_mir_transform/src/known_panics_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/lint/ice-unions-known-panics-lint-issue-121534.rs
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 218be27

Please sign in to comment.