Fix unsound optimization with explicit variant discriminants
This commit is contained in:
parent
edebf77e00
commit
529c35331b
2 changed files with 32 additions and 4 deletions
|
@ -706,12 +706,22 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
|
|||
let helper = |rhs: &Rvalue<'tcx>,
|
||||
place: &Place<'tcx>,
|
||||
variant_index: &VariantIdx,
|
||||
switch_value: u128,
|
||||
side_to_choose| {
|
||||
let place_type = place.ty(self.body, self.tcx).ty;
|
||||
let adt = match *place_type.kind() {
|
||||
ty::Adt(adt, _) if adt.is_enum() => adt,
|
||||
_ => return StatementEquality::NotEqual,
|
||||
};
|
||||
let variant_discr = adt.discriminant_for_variant(self.tcx, *variant_index).val;
|
||||
if variant_discr != switch_value {
|
||||
trace!(
|
||||
"NO: variant discriminant {} does not equal switch value {}",
|
||||
variant_discr,
|
||||
switch_value
|
||||
);
|
||||
return StatementEquality::NotEqual;
|
||||
}
|
||||
let variant_is_fieldless = adt.variants[*variant_index].fields.is_empty();
|
||||
if !variant_is_fieldless {
|
||||
trace!("NO: variant {:?} was not fieldless", variant_index);
|
||||
|
@ -742,18 +752,18 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
|
|||
StatementKind::SetDiscriminant { place, variant_index },
|
||||
)
|
||||
// we need to make sure that the switch value that targets the bb with SetDiscriminant (y), is the same as the variant index
|
||||
if Some(variant_index.index() as u128) == y_target_and_value.value => {
|
||||
if y_target_and_value.value.is_some() => {
|
||||
// choose basic block of x, as that has the assign
|
||||
helper(rhs, place, variant_index, x_target_and_value.target)
|
||||
helper(rhs, place, variant_index, y_target_and_value.value.unwrap(), x_target_and_value.target)
|
||||
}
|
||||
(
|
||||
StatementKind::SetDiscriminant { place, variant_index },
|
||||
StatementKind::Assign(box (_, rhs)),
|
||||
)
|
||||
// we need to make sure that the switch value that targets the bb with SetDiscriminant (x), is the same as the variant index
|
||||
if Some(variant_index.index() as u128) == x_target_and_value.value => {
|
||||
if x_target_and_value.value.is_some() => {
|
||||
// choose basic block of y, as that has the assign
|
||||
helper(rhs, place, variant_index, y_target_and_value.target)
|
||||
helper(rhs, place, variant_index, x_target_and_value.value.unwrap(), y_target_and_value.target)
|
||||
}
|
||||
_ => {
|
||||
trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue