From d86acdd72a823fa496b3501c9d656beedf9f124f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannis=20Christopher=20K=C3=B6hl?= Date: Sun, 23 Oct 2022 14:49:38 +0200 Subject: [PATCH] Prevent propagation of overflow if overflow occured --- .../src/dataflow_const_prop.rs | 20 ++++--------------- .../checked.main.DataflowConstProp.diff | 2 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index b4078625d83d..8cb1a9dc4a1d 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -11,7 +11,7 @@ use rustc_mir_dataflow::value_analysis::{ HasTop, Map, State, TrackElem, ValueAnalysis, ValueOrPlace, ValueOrPlaceOrRef, }; use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects}; -use rustc_span::{sym, DUMMY_SP}; +use rustc_span::DUMMY_SP; use crate::MirPass; @@ -42,7 +42,6 @@ struct ConstAnalysis<'tcx> { tcx: TyCtxt<'tcx>, ecx: InterpCx<'tcx, 'tcx, DummyMachine>, param_env: ty::ParamEnv<'tcx>, - propagate_overflow: bool, } impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> { @@ -84,13 +83,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> { let overflow = match overflow { FlatSet::Top => FlatSet::Top, FlatSet::Elem(overflow) => { - if overflow && !self.propagate_overflow { + if overflow { + // Overflow cannot be reliable propagated. See: https://github.com/rust-lang/rust/pull/101168#issuecomment-1288091446 FlatSet::Top } else { - self.wrap_scalar( - Scalar::from_bool(overflow), - self.tcx.types.bool, - ) + self.wrap_scalar(Scalar::from_bool(false), self.tcx.types.bool) } } FlatSet::Bottom => FlatSet::Bottom, @@ -220,20 +217,11 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> { impl<'tcx> ConstAnalysis<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, map: Map) -> Self { - // It can happen that overflow will be detected even though overflow checks are disabled. - // This is caused by inlining functions that have #[rustc_inherit_overflow_checks]. Such - // overflows must not be propagated if `-C overflow-checks=off`. Also, if the function we - // are optimizing here has #[rustc_inherit_overflow_checks], the overflow checks may - // actually not be triggered by the consuming crate, so we have to ignore them too. - // Related to https://github.com/rust-lang/rust/issues/35310. - let propagate_overflow = tcx.sess.overflow_checks() - && !tcx.has_attr(body.source.def_id(), sym::rustc_inherit_overflow_checks); Self { map, tcx, ecx: InterpCx::new(tcx, DUMMY_SP, ty::ParamEnv::empty(), DummyMachine), param_env: tcx.param_env(body.source.def_id()), - propagate_overflow, } } diff --git a/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff index 944afed8f465..a4ebd0c8c18f 100644 --- a/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff +++ b/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff @@ -61,7 +61,7 @@ - assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18 + _9 = const i32::MAX; // scope 4 at $DIR/checked.rs:+6:13: +6:14 + _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18 -+ assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18 ++ assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18 } bb2: {