about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-23 08:23:00 +0000
committerbors <bors@rust-lang.org>2020-09-23 08:23:00 +0000
commitfeca2c229e209ceda1eda7306e6ea9ee0aaa9305 (patch)
treeb657aa952a045e1cc80f36c3b0409feca1bdee82 /compiler
parentf6d59207ad56e24a2bfefa3544de48a0f6491363 (diff)
parente5447a22222ecc6a650e75282cb9931b910854b2 (diff)
downloadrust-feca2c229e209ceda1eda7306e6ea9ee0aaa9305.tar.gz
rust-feca2c229e209ceda1eda7306e6ea9ee0aaa9305.zip
Auto merge of #76659 - simonvandel:76432, r=oli-obk
SimplifyComparisonIntegral: fix miscompilation

Fixes #76432
Only insert StorageDeads if we actually removed one.
Fixes an issue where we added StorageDead to a place with no StorageLive

r? `@oli-obk`
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_mir/src/transform/simplify_comparison_integral.rs43
1 files changed, 22 insertions, 21 deletions
diff --git a/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
index a450a75d091..9b460c9ecb1 100644
--- a/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
@@ -61,26 +61,6 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
                 _ => unreachable!(),
             }
 
-            let terminator = bb.terminator_mut();
-
-            // add StorageDead for the place switched on at the top of each target
-            for bb_idx in new_targets.iter() {
-                storage_deads_to_insert.push((
-                    *bb_idx,
-                    Statement {
-                        source_info: terminator.source_info,
-                        kind: StatementKind::StorageDead(opt.to_switch_on.local),
-                    },
-                ));
-            }
-
-            terminator.kind = TerminatorKind::SwitchInt {
-                discr: Operand::Move(opt.to_switch_on),
-                switch_ty: opt.branch_value_ty,
-                values: vec![new_value].into(),
-                targets: new_targets,
-            };
-
             // delete comparison statement if it the value being switched on was moved, which means it can not be user later on
             if opt.can_remove_bin_op_stmt {
                 bb.statements[opt.bin_op_stmt_idx].make_nop();
@@ -106,14 +86,35 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
                 }
             }
 
+            let terminator = bb.terminator();
+
             // remove StorageDead (if it exists) being used in the assign of the comparison
             for (stmt_idx, stmt) in bb.statements.iter().enumerate() {
                 if !matches!(stmt.kind, StatementKind::StorageDead(local) if local == opt.to_switch_on.local)
                 {
                     continue;
                 }
-                storage_deads_to_remove.push((stmt_idx, opt.bb_idx))
+                storage_deads_to_remove.push((stmt_idx, opt.bb_idx));
+                // if we have StorageDeads to remove then make sure to insert them at the top of each target
+                for bb_idx in new_targets.iter() {
+                    storage_deads_to_insert.push((
+                        *bb_idx,
+                        Statement {
+                            source_info: terminator.source_info,
+                            kind: StatementKind::StorageDead(opt.to_switch_on.local),
+                        },
+                    ));
+                }
             }
+
+            let terminator = bb.terminator_mut();
+
+            terminator.kind = TerminatorKind::SwitchInt {
+                discr: Operand::Move(opt.to_switch_on),
+                switch_ty: opt.branch_value_ty,
+                values: vec![new_value].into(),
+                targets: new_targets,
+            };
         }
 
         for (idx, bb_idx) in storage_deads_to_remove {