Skip to content

Commit a48d83d

Browse files
authored
Rollup merge of #109234 - tmiasko:overflow-checks, r=cjgillot
Tweak implementation of overflow checking assertions Extract and reuse logic controlling behaviour of overflow checking assertions instead of duplicating it three times. r? `@cjgillot`
2 parents a79925d + 27b430b commit a48d83d

File tree

7 files changed

+19
-41
lines changed

7 files changed

+19
-41
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -346,17 +346,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
346346
crate::abi::codegen_return(fx);
347347
}
348348
TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
349-
if !fx.tcx.sess.overflow_checks() {
350-
let overflow_not_to_check = match msg {
351-
AssertKind::OverflowNeg(..) => true,
352-
AssertKind::Overflow(op, ..) => op.is_checkable(),
353-
_ => false,
354-
};
355-
if overflow_not_to_check {
356-
let target = fx.get_block(*target);
357-
fx.bcx.ins().jump(target, &[]);
358-
continue;
359-
}
349+
if !fx.tcx.sess.overflow_checks() && msg.is_optional_overflow_check() {
350+
let target = fx.get_block(*target);
351+
fx.bcx.ins().jump(target, &[]);
352+
continue;
360353
}
361354
let cond = codegen_operand(fx, cond).load_scalar(fx);
362355

compiler/rustc_codegen_ssa/src/mir/block.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -563,15 +563,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
563563
// with #[rustc_inherit_overflow_checks] and inlined from
564564
// another crate (mostly core::num generic/#[inline] fns),
565565
// while the current crate doesn't use overflow checks.
566-
if !bx.cx().check_overflow() {
567-
let overflow_not_to_check = match msg {
568-
AssertKind::OverflowNeg(..) => true,
569-
AssertKind::Overflow(op, ..) => op.is_checkable(),
570-
_ => false,
571-
};
572-
if overflow_not_to_check {
573-
const_cond = Some(expected);
574-
}
566+
if !bx.cx().check_overflow() && msg.is_optional_overflow_check() {
567+
const_cond = Some(expected);
575568
}
576569

577570
// Don't codegen the panic block if success if known.

compiler/rustc_const_eval/src/interpret/machine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
155155

156156
/// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually
157157
/// check for overflow.
158-
fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
158+
fn ignore_optional_overflow_checks(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
159159

160160
/// Entry point for obtaining the MIR of anything that should get evaluated.
161161
/// So not just functions and shims, but also const/static initializers, anonymous
@@ -474,7 +474,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
474474
}
475475

476476
#[inline(always)]
477-
fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
477+
fn ignore_optional_overflow_checks(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
478478
false
479479
}
480480

compiler/rustc_const_eval/src/interpret/terminator.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
138138
}
139139

140140
Assert { ref cond, expected, ref msg, target, cleanup } => {
141-
let ignored = M::ignore_checkable_overflow_assertions(self)
142-
&& match msg {
143-
mir::AssertKind::OverflowNeg(..) => true,
144-
mir::AssertKind::Overflow(op, ..) => op.is_checkable(),
145-
_ => false,
146-
};
141+
let ignored =
142+
M::ignore_optional_overflow_checks(self) && msg.is_optional_overflow_check();
147143
let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?;
148144
if ignored || expected == cond_val {
149145
self.go_to_block(target);

compiler/rustc_middle/src/mir/mod.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,13 @@ impl<'tcx> BasicBlockData<'tcx> {
12681268
}
12691269

12701270
impl<O> AssertKind<O> {
1271+
/// Returns true if this an overflow checking assertion controlled by -C overflow-checks.
1272+
pub fn is_optional_overflow_check(&self) -> bool {
1273+
use AssertKind::*;
1274+
use BinOp::*;
1275+
matches!(self, OverflowNeg(..) | Overflow(Add | Sub | Mul | Shl | Shr, ..))
1276+
}
1277+
12711278
/// Getting a description does not require `O` to be printable, and does not
12721279
/// require allocation.
12731280
/// The caller is expected to handle `BoundsCheck` separately.
@@ -1992,16 +1999,6 @@ impl BorrowKind {
19921999
}
19932000
}
19942001

1995-
impl BinOp {
1996-
/// The checkable operators are those whose overflow checking behavior is controlled by
1997-
/// -Coverflow-checks option. The remaining operators have either no overflow conditions (e.g.,
1998-
/// BitAnd, BitOr, BitXor) or are always checked for overflow (e.g., Div, Rem).
1999-
pub fn is_checkable(self) -> bool {
2000-
use self::BinOp::*;
2001-
matches!(self, Add | Sub | Mul | Shl | Shr)
2002-
}
2003-
}
2004-
20052002
impl<'tcx> Debug for Rvalue<'tcx> {
20062003
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
20072004
use self::Rvalue::*;

compiler/rustc_middle/src/mir/syntax.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,7 @@ pub enum TerminatorKind<'tcx> {
646646
/// When overflow checking is disabled and this is run-time MIR (as opposed to compile-time MIR
647647
/// that is used for CTFE), the following variants of this terminator behave as `goto target`:
648648
/// - `OverflowNeg(..)`,
649-
/// - `Overflow(op, ..)` if op is a "checkable" operation (add, sub, mul, shl, shr, but NOT
650-
/// div or rem).
649+
/// - `Overflow(op, ..)` if op is add, sub, mul, shl, shr, but NOT div or rem.
651650
Assert {
652651
cond: Operand<'tcx>,
653652
expected: bool,

src/tools/miri/src/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
822822
}
823823

824824
#[inline(always)]
825-
fn ignore_checkable_overflow_assertions(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
825+
fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
826826
!ecx.tcx.sess.overflow_checks()
827827
}
828828

0 commit comments

Comments
 (0)