Skip to content

Commit

Permalink
Unrolled build for rust-lang#121628
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#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 rust-lang#121534
  • Loading branch information
rust-timer authored Feb 26, 2024
2 parents b79db43 + 633c92c commit 214544b
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 214544b

Please sign in to comment.