Skip to content

Commit

Permalink
add test for shift with negative RHS
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Sep 12, 2023
1 parent 47689ff commit a7c8ed3
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
8 changes: 4 additions & 4 deletions clippy_utils/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
// sign extend
let value = sext(self.lcx.tcx, value, ity);

// Applying unary - to the most negative value of any signed integer type panicks.
// Applying unary - to the most negative value of any signed integer type panics.
if value == min {
return None;
}
Expand Down Expand Up @@ -638,22 +638,22 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
let r = sext(self.lcx.tcx, r, ity);

// Using / or %, where the left-hand argument is the smallest integer of a signed integer type and
// the right-hand argument is -1 always panicks, even with overflow-checks disabled
// the right-hand argument is -1 always panics, even with overflow-checks disabled
if l == ty_min_value && r == -1 {
return None;
}

let zext = |n: i128| Constant::Int(unsext(self.lcx.tcx, n, ity));
match op.node {
// When +, * or binary - create a value greater than the maximum value, or less than
// the minimum value that can be stored, it panicks.
// the minimum value that can be stored, it panics.
BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(zext),
BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(zext),
BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(zext),
BinOpKind::Div if r != 0 => l.checked_div(r).map(zext),
BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext),
// Using << or >> where the right-hand argument is greater than or equal to the number of bits
// in the type of the left-hand argument, or is negative panicks.
// in the type of the left-hand argument, or is negative panics.
BinOpKind::Shr if r < bits && !r.is_negative() => l.checked_shr(r.try_into().ok()?).map(zext),
BinOpKind::Shl if r < bits && !r.is_negative() => l.checked_shl(r.try_into().ok()?).map(zext),
BinOpKind::BitXor => Some(zext(l ^ r)),
Expand Down
15 changes: 11 additions & 4 deletions tests/ui/unnecessary_lazy_eval.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,21 @@ fn issue9422(x: usize) -> Option<usize> {
fn panicky_arithmetic_ops(x: usize) {
let _x = false.then(|| i32::MAX + 1); // don't lint
let _x = false.then(|| i32::MAX * 2); // don't lint
let _x = false.then_some(i32::MAX - 1); // lint
let _x = false.then_some(i32::MAX - 1);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| i32::MIN - 1); // don't lint
#[allow(clippy::identity_op)]
let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); // lint
let _x = false.then_some(255u8 << 7); // lint
let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then_some(255u8 << 7);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| 255u8 << 8); // don't lint
let _x = false.then(|| 255u8 >> 8); // don't lint
let _x = false.then(|| 255u8 >> x); // don't lint
let _x = false.then(|| i32::MIN / -1); // don't lint
let _x = false.then_some(-i32::MAX); // lint
let _x = false.then_some(-i32::MAX);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| -i32::MIN); // don't lint
let _x = false.then(|| 255 >> -7); // don't lint
let _x = false.then(|| 255 << -1); // don't lint
}
15 changes: 11 additions & 4 deletions tests/ui/unnecessary_lazy_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,21 @@ fn issue9422(x: usize) -> Option<usize> {
fn panicky_arithmetic_ops(x: usize) {
let _x = false.then(|| i32::MAX + 1); // don't lint
let _x = false.then(|| i32::MAX * 2); // don't lint
let _x = false.then(|| i32::MAX - 1); // lint
let _x = false.then(|| i32::MAX - 1);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| i32::MIN - 1); // don't lint
#[allow(clippy::identity_op)]
let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); // lint
let _x = false.then(|| 255u8 << 7); // lint
let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| 255u8 << 7);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| 255u8 << 8); // don't lint
let _x = false.then(|| 255u8 >> 8); // don't lint
let _x = false.then(|| 255u8 >> x); // don't lint
let _x = false.then(|| i32::MIN / -1); // don't lint
let _x = false.then(|| -i32::MAX); // lint
let _x = false.then(|| -i32::MAX);
//~^ ERROR: unnecessary closure used with `bool::then`
let _x = false.then(|| -i32::MIN); // don't lint
let _x = false.then(|| 255 >> -7); // don't lint
let _x = false.then(|| 255 << -1); // don't lint
}
14 changes: 7 additions & 7 deletions tests/ui/unnecessary_lazy_eval.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -315,31 +315,31 @@ LL | | or_else(|_| Ok(ext_str.some_field));
error: unnecessary closure used with `bool::then`
--> $DIR/unnecessary_lazy_eval.rs:205:14
|
LL | let _x = false.then(|| i32::MAX - 1); // lint
LL | let _x = false.then(|| i32::MAX - 1);
| ^^^^^^---------------------
| |
| help: use `then_some(..)` instead: `then_some(i32::MAX - 1)`

error: unnecessary closure used with `bool::then`
--> $DIR/unnecessary_lazy_eval.rs:207:14
--> $DIR/unnecessary_lazy_eval.rs:209:14
|
LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); // lint
LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);
| ^^^^^^-------------------------------------
| |
| help: use `then_some(..)` instead: `then_some((1 + 2 * 3 - 2 / 3 + 9) << 2)`

error: unnecessary closure used with `bool::then`
--> $DIR/unnecessary_lazy_eval.rs:208:14
--> $DIR/unnecessary_lazy_eval.rs:211:14
|
LL | let _x = false.then(|| 255u8 << 7); // lint
LL | let _x = false.then(|| 255u8 << 7);
| ^^^^^^-------------------
| |
| help: use `then_some(..)` instead: `then_some(255u8 << 7)`

error: unnecessary closure used with `bool::then`
--> $DIR/unnecessary_lazy_eval.rs:213:14
--> $DIR/unnecessary_lazy_eval.rs:217:14
|
LL | let _x = false.then(|| -i32::MAX); // lint
LL | let _x = false.then(|| -i32::MAX);
| ^^^^^^------------------
| |
| help: use `then_some(..)` instead: `then_some(-i32::MAX)`
Expand Down

0 comments on commit a7c8ed3

Please sign in to comment.