about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-06 17:45:39 -0700
committerGitHub <noreply@github.com>2020-07-06 17:45:39 -0700
commit38f5151d3ff19d772deac0c6724ff8bde1d5c79f (patch)
tree07e273310cb56dcdc4d862b2bffa352ff0692f7b
parent50e22bddcfd22d216763662e46fb5a6e5d10ae73 (diff)
parentee8dd4e3cce3bf158a31e50205ee3ebd76c40370 (diff)
downloadrust-38f5151d3ff19d772deac0c6724ff8bde1d5c79f.tar.gz
rust-38f5151d3ff19d772deac0c6724ff8bde1d5c79f.zip
Rollup merge of #74102 - oli-obk:const_prop_icde, r=wesleywiser
Fix const prop ICE

we used to erase the local just before we tried to read it for diagnostics

fixes #73993

r? @wesleywiser
-rw-r--r--src/librustc_mir/transform/const_prop.rs40
-rw-r--r--src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs9
2 files changed, 30 insertions, 19 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index e4c1ca4e851..fbe3377d875 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -1004,14 +1004,6 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                     let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected));
                     let value_const = self.ecx.read_scalar(value).unwrap();
                     if expected != value_const {
-                        // Poison all places this operand references so that further code
-                        // doesn't use the invalid value
-                        match cond {
-                            Operand::Move(ref place) | Operand::Copy(ref place) => {
-                                Self::remove_const(&mut self.ecx, place.local);
-                            }
-                            Operand::Constant(_) => {}
-                        }
                         let mut eval_to_int = |op| {
                             let op = self
                                 .eval_operand(op, source_info)
@@ -1020,27 +1012,37 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                         };
                         let msg = match msg {
                             AssertKind::DivisionByZero(op) => {
-                                AssertKind::DivisionByZero(eval_to_int(op))
+                                Some(AssertKind::DivisionByZero(eval_to_int(op)))
                             }
                             AssertKind::RemainderByZero(op) => {
-                                AssertKind::RemainderByZero(eval_to_int(op))
+                                Some(AssertKind::RemainderByZero(eval_to_int(op)))
                             }
                             AssertKind::BoundsCheck { ref len, ref index } => {
                                 let len = eval_to_int(len);
                                 let index = eval_to_int(index);
-                                AssertKind::BoundsCheck { len, index }
+                                Some(AssertKind::BoundsCheck { len, index })
                             }
                             // Overflow is are already covered by checks on the binary operators.
-                            AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => return,
+                            AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => None,
                             // Need proper const propagator for these.
-                            _ => return,
+                            _ => None,
                         };
-                        self.report_assert_as_lint(
-                            lint::builtin::UNCONDITIONAL_PANIC,
-                            source_info,
-                            "this operation will panic at runtime",
-                            msg,
-                        );
+                        // Poison all places this operand references so that further code
+                        // doesn't use the invalid value
+                        match cond {
+                            Operand::Move(ref place) | Operand::Copy(ref place) => {
+                                Self::remove_const(&mut self.ecx, place.local);
+                            }
+                            Operand::Constant(_) => {}
+                        }
+                        if let Some(msg) = msg {
+                            self.report_assert_as_lint(
+                                lint::builtin::UNCONDITIONAL_PANIC,
+                                source_info,
+                                "this operation will panic at runtime",
+                                msg,
+                            );
+                        }
                     } else {
                         if self.should_const_prop(value) {
                             if let ScalarMaybeUninit::Scalar(scalar) = value_const {
diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
new file mode 100644
index 00000000000..5f2d5e80243
--- /dev/null
+++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+pub struct Fixed64(i64);
+
+pub fn div(f: Fixed64) {
+    f.0 / 0;
+}
+
+fn main() {}