Skip to content

Commit 27b430b

Browse files
committed
Tweak implementation of overflow checking assertions
Extract and reuse logic controlling behaviour of overflow checking assertions instead of duplicating it three times.
1 parent e386217 commit 27b430b

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
@@ -1274,6 +1274,13 @@ impl<'tcx> BasicBlockData<'tcx> {
12741274
}
12751275

12761276
impl<O> AssertKind<O> {
1277+
/// Returns true if this an overflow checking assertion controlled by -C overflow-checks.
1278+
pub fn is_optional_overflow_check(&self) -> bool {
1279+
use AssertKind::*;
1280+
use BinOp::*;
1281+
matches!(self, OverflowNeg(..) | Overflow(Add | Sub | Mul | Shl | Shr, ..))
1282+
}
1283+
12771284
/// Getting a description does not require `O` to be printable, and does not
12781285
/// require allocation.
12791286
/// The caller is expected to handle `BoundsCheck` separately.
@@ -1998,16 +2005,6 @@ impl BorrowKind {
19982005
}
19992006
}
20002007

2001-
impl BinOp {
2002-
/// The checkable operators are those whose overflow checking behavior is controlled by
2003-
/// -Coverflow-checks option. The remaining operators have either no overflow conditions (e.g.,
2004-
/// BitAnd, BitOr, BitXor) or are always checked for overflow (e.g., Div, Rem).
2005-
pub fn is_checkable(self) -> bool {
2006-
use self::BinOp::*;
2007-
matches!(self, Add | Sub | Mul | Shl | Shr)
2008-
}
2009-
}
2010-
20112008
impl<'tcx> Debug for Rvalue<'tcx> {
20122009
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
20132010
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)