Skip to content

Commit fc90124

Browse files
committed
test exact_div UB detection
1 parent 14c4192 commit fc90124

File tree

5 files changed

+27
-1
lines changed

5 files changed

+27
-1
lines changed

src/intrinsic.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
272272
let b = this.read_immediate(args[1])?;
273273
// check x % y != 0
274274
if this.binary_op(mir::BinOp::Rem, a, b)?.0.to_bits(dest.layout.size)? != 0 {
275-
return err!(ValidationFailure(format!("exact_div: {:?} cannot be divided by {:?}", a, b)));
275+
// Check if `b` is -1, which is the "min_value / -1" case.
276+
let minus1 = Scalar::from_int(-1, dest.layout.size);
277+
return if b.to_scalar().unwrap() == minus1 {
278+
err!(Intrinsic(format!("exact_div: result of dividing MIN by -1 cannot be represented")))
279+
} else {
280+
err!(Intrinsic(format!("exact_div: {:?} cannot be divided by {:?} without remainder", *a, *b)))
281+
};
276282
}
277283
this.binop_ignore_overflow(mir::BinOp::Div, a, b, dest)?;
278284
},

tests/compile-fail/exact_div1.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// divison by 0
4+
unsafe { std::intrinsics::exact_div(2, 0); } //~ ERROR divisor of zero
5+
}

tests/compile-fail/exact_div2.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// divison with a remainder
4+
unsafe { std::intrinsics::exact_div(2u16, 3); } //~ ERROR Scalar(0x0002) cannot be divided by Scalar(0x0003) without remainder
5+
}

tests/compile-fail/exact_div3.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// signed divison with a remainder
4+
unsafe { std::intrinsics::exact_div(-19i8, 2); } //~ ERROR Scalar(0xed) cannot be divided by Scalar(0x02) without remainder
5+
}

tests/compile-fail/exact_div4.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_intrinsics)]
2+
fn main() {
3+
// divison of min_value by -1
4+
unsafe { std::intrinsics::exact_div(i64::min_value(), -1); } //~ ERROR result of dividing MIN by -1 cannot be represented
5+
}

0 commit comments

Comments
 (0)