Add guards/tests for div,rem overflow cases
This commit is contained in:
parent
b931c15c0b
commit
c67fc2e4c5
2 changed files with 84 additions and 2 deletions
|
|
@ -283,13 +283,20 @@ macro_rules! impl_unsigned_int_ops {
|
|||
|
||||
#[inline]
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
// TODO there is probably a better way of doing this
|
||||
if AsRef::<[$scalar]>::as_ref(&rhs)
|
||||
if rhs.as_slice()
|
||||
.iter()
|
||||
.any(|x| *x == 0)
|
||||
{
|
||||
panic!("attempt to divide by zero");
|
||||
}
|
||||
|
||||
// Guards for div(MIN, -1),
|
||||
// this check only applies to signed ints
|
||||
if <$scalar>::MIN != 0 && self.as_slice().iter()
|
||||
.zip(rhs.as_slice().iter())
|
||||
.any(|(x,y)| *x == <$scalar>::MIN && *y == -1 as _) {
|
||||
panic!("attempt to divide with overflow");
|
||||
}
|
||||
unsafe { crate::intrinsics::simd_div(self, rhs) }
|
||||
}
|
||||
}
|
||||
|
|
@ -304,6 +311,11 @@ macro_rules! impl_unsigned_int_ops {
|
|||
if rhs == 0 {
|
||||
panic!("attempt to divide by zero");
|
||||
}
|
||||
if <$scalar>::MIN != 0 &&
|
||||
self.as_slice().iter().any(|x| *x == <$scalar>::MIN) &&
|
||||
rhs == -1 as _ {
|
||||
panic!("attempt to divide with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { crate::intrinsics::simd_div(self, rhs) }
|
||||
}
|
||||
|
|
@ -353,6 +365,14 @@ macro_rules! impl_unsigned_int_ops {
|
|||
{
|
||||
panic!("attempt to calculate the remainder with a divisor of zero");
|
||||
}
|
||||
|
||||
// Guards for rem(MIN, -1)
|
||||
// this branch applies the check only to signed ints
|
||||
if <$scalar>::MIN != 0 && self.as_slice().iter()
|
||||
.zip(rhs.as_slice().iter())
|
||||
.any(|(x,y)| *x == <$scalar>::MIN && *y == -1 as _) {
|
||||
panic!("attempt to calculate the remainder with overflow");
|
||||
}
|
||||
unsafe { crate::intrinsics::simd_rem(self, rhs) }
|
||||
}
|
||||
}
|
||||
|
|
@ -367,6 +387,11 @@ macro_rules! impl_unsigned_int_ops {
|
|||
if rhs == 0 {
|
||||
panic!("attempt to calculate the remainder with a divisor of zero");
|
||||
}
|
||||
if <$scalar>::MIN != 0 &&
|
||||
self.as_slice().iter().any(|x| *x == <$scalar>::MIN) &&
|
||||
rhs == -1 as _ {
|
||||
panic!("attempt to calculate the remainder with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { crate::intrinsics::simd_rem(self, rhs) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,6 +228,39 @@ macro_rules! int_tests {
|
|||
assert_biteq!(a, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn div_min_panics() {
|
||||
let a = from_slice(&vec![$scalar::MIN; 64]);
|
||||
let b = from_slice(&vec![-1; 64]);
|
||||
let _ = a / b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn div_by_all_zeros_panics() {
|
||||
let a = from_slice(&A);
|
||||
let b = from_slice(&vec![0 ; 64]);
|
||||
let _ = a / b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn div_by_one_zero_panics() {
|
||||
let a = from_slice(&A);
|
||||
let mut b = from_slice(&B);
|
||||
b[0] = 0 as _;
|
||||
let _ = a / b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn div_min_neg_one_no_panic() {
|
||||
let a = from_slice(&A);
|
||||
let b = from_slice(&vec![-1; 64]);
|
||||
let _ = a / b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn rem() {
|
||||
|
|
@ -275,6 +308,30 @@ macro_rules! int_tests {
|
|||
assert_biteq!(a, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn rem_min_neg_one_no_panic() {
|
||||
let a = from_slice(&A);
|
||||
let b = from_slice(&vec![-1; 64]);
|
||||
let _ = a % b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn rem_min_panic() {
|
||||
let a = from_slice(&vec![$scalar::MIN; 64]);
|
||||
let b = from_slice(&vec![-1 ; 64]);
|
||||
let _ = a % b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn rem_min_zero_panic() {
|
||||
let a = from_slice(&A);
|
||||
let b = from_slice(&vec![0 ; 64]);
|
||||
let _ = a % b;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
|
||||
fn bitand() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue