Fix subtraction overflow in cast_possible_truncation

This commit is contained in:
Alex Macleod 2022-04-11 18:54:44 +01:00
parent c7e6863843
commit 4a21082da2
3 changed files with 33 additions and 15 deletions

View file

@ -29,21 +29,19 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
ExprKind::Block(block, _) => block.expr.map_or(nbits, |e| apply_reductions(cx, nbits, e, signed)),
ExprKind::Binary(op, left, right) => match op.node {
BinOpKind::Div => {
apply_reductions(cx, nbits, left, signed)
- (if signed {
0 // let's be conservative here
} else {
// by dividing by 1, we remove 0 bits, etc.
get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
})
apply_reductions(cx, nbits, left, signed).saturating_sub(if signed {
// let's be conservative here
0
} else {
// by dividing by 1, we remove 0 bits, etc.
get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
})
},
BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right)
.unwrap_or(u64::max_value())
.min(apply_reductions(cx, nbits, left, signed)),
BinOpKind::Shr => {
apply_reductions(cx, nbits, left, signed)
- constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))
},
BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
.saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
_ => nbits,
},
ExprKind::MethodCall(method, [left, right], _) => {

View file

@ -1,13 +1,13 @@
#![feature(repr128)]
#![allow(incomplete_features)]
#[warn(
#![warn(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_possible_wrap
)]
#[allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
#![allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
fn main() {
// Test clippy::cast_precision_loss
let x0 = 1i32;
@ -252,3 +252,11 @@ fn main() {
}
}
}
fn avoid_subtract_overflow(q: u32) {
let c = (q >> 16) as u8;
c as usize;
let c = (q / 1000) as u8;
c as usize;
}

View file

@ -194,5 +194,17 @@ error: casting `main::E10` to `u16` may truncate the value
LL | let _ = self as u16;
| ^^^^^^^^^^^
error: aborting due to 31 previous errors
error: casting `u32` to `u8` may truncate the value
--> $DIR/cast.rs:257:13
|
LL | let c = (q >> 16) as u8;
| ^^^^^^^^^^^^^^^
error: casting `u32` to `u8` may truncate the value
--> $DIR/cast.rs:260:13
|
LL | let c = (q / 1000) as u8;
| ^^^^^^^^^^^^^^^^
error: aborting due to 33 previous errors