From fc901244890cf2c0218027189d9d2311026dabbd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Jun 2019 10:51:08 +0200 Subject: [PATCH] test exact_div UB detection --- src/intrinsic.rs | 8 +++++++- tests/compile-fail/exact_div1.rs | 5 +++++ tests/compile-fail/exact_div2.rs | 5 +++++ tests/compile-fail/exact_div3.rs | 5 +++++ tests/compile-fail/exact_div4.rs | 5 +++++ 5 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/compile-fail/exact_div1.rs create mode 100644 tests/compile-fail/exact_div2.rs create mode 100644 tests/compile-fail/exact_div3.rs create mode 100644 tests/compile-fail/exact_div4.rs diff --git a/src/intrinsic.rs b/src/intrinsic.rs index cd89055b467..cf2afe0a811 100644 --- a/src/intrinsic.rs +++ b/src/intrinsic.rs @@ -272,7 +272,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let b = this.read_immediate(args[1])?; // check x % y != 0 if this.binary_op(mir::BinOp::Rem, a, b)?.0.to_bits(dest.layout.size)? != 0 { - return err!(ValidationFailure(format!("exact_div: {:?} cannot be divided by {:?}", a, b))); + // Check if `b` is -1, which is the "min_value / -1" case. + let minus1 = Scalar::from_int(-1, dest.layout.size); + return if b.to_scalar().unwrap() == minus1 { + err!(Intrinsic(format!("exact_div: result of dividing MIN by -1 cannot be represented"))) + } else { + err!(Intrinsic(format!("exact_div: {:?} cannot be divided by {:?} without remainder", *a, *b))) + }; } this.binop_ignore_overflow(mir::BinOp::Div, a, b, dest)?; }, diff --git a/tests/compile-fail/exact_div1.rs b/tests/compile-fail/exact_div1.rs new file mode 100644 index 00000000000..171bedeadc6 --- /dev/null +++ b/tests/compile-fail/exact_div1.rs @@ -0,0 +1,5 @@ +#![feature(core_intrinsics)] +fn main() { + // divison by 0 + unsafe { std::intrinsics::exact_div(2, 0); } //~ ERROR divisor of zero +} diff --git a/tests/compile-fail/exact_div2.rs b/tests/compile-fail/exact_div2.rs new file mode 100644 index 00000000000..22bcf027dd0 --- /dev/null +++ b/tests/compile-fail/exact_div2.rs @@ -0,0 +1,5 @@ +#![feature(core_intrinsics)] +fn main() { + // divison with a remainder + unsafe { std::intrinsics::exact_div(2u16, 3); } //~ ERROR Scalar(0x0002) cannot be divided by Scalar(0x0003) without remainder +} diff --git a/tests/compile-fail/exact_div3.rs b/tests/compile-fail/exact_div3.rs new file mode 100644 index 00000000000..2db62e0092d --- /dev/null +++ b/tests/compile-fail/exact_div3.rs @@ -0,0 +1,5 @@ +#![feature(core_intrinsics)] +fn main() { + // signed divison with a remainder + unsafe { std::intrinsics::exact_div(-19i8, 2); } //~ ERROR Scalar(0xed) cannot be divided by Scalar(0x02) without remainder +} diff --git a/tests/compile-fail/exact_div4.rs b/tests/compile-fail/exact_div4.rs new file mode 100644 index 00000000000..736d4f2516d --- /dev/null +++ b/tests/compile-fail/exact_div4.rs @@ -0,0 +1,5 @@ +#![feature(core_intrinsics)] +fn main() { + // divison of min_value by -1 + unsafe { std::intrinsics::exact_div(i64::min_value(), -1); } //~ ERROR result of dividing MIN by -1 cannot be represented +}