Skip to content

Commit 636ed84

Browse files
committed
Auto merge of #8687 - Alexendoo:cast-possible-truncation-overflow, r=xFrednet
Fix subtraction overflow in `cast_possible_truncation` changelog: Fix false negative due to subtraction overflow in `cast_possible_truncation` I *think* a false negative is the worst that can happen from this
2 parents 89ee6aa + 4a21082 commit 636ed84

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

clippy_lints/src/casts/cast_possible_truncation.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,19 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
2929
ExprKind::Block(block, _) => block.expr.map_or(nbits, |e| apply_reductions(cx, nbits, e, signed)),
3030
ExprKind::Binary(op, left, right) => match op.node {
3131
BinOpKind::Div => {
32-
apply_reductions(cx, nbits, left, signed)
33-
- (if signed {
34-
0 // let's be conservative here
35-
} else {
36-
// by dividing by 1, we remove 0 bits, etc.
37-
get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
38-
})
32+
apply_reductions(cx, nbits, left, signed).saturating_sub(if signed {
33+
// let's be conservative here
34+
0
35+
} else {
36+
// by dividing by 1, we remove 0 bits, etc.
37+
get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
38+
})
3939
},
4040
BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right)
4141
.unwrap_or(u64::max_value())
4242
.min(apply_reductions(cx, nbits, left, signed)),
43-
BinOpKind::Shr => {
44-
apply_reductions(cx, nbits, left, signed)
45-
- constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))
46-
},
43+
BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
44+
.saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
4745
_ => nbits,
4846
},
4947
ExprKind::MethodCall(method, [left, right], _) => {

tests/ui/cast.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#![feature(repr128)]
22
#![allow(incomplete_features)]
3-
4-
#[warn(
3+
#![warn(
54
clippy::cast_precision_loss,
65
clippy::cast_possible_truncation,
76
clippy::cast_sign_loss,
87
clippy::cast_possible_wrap
98
)]
10-
#[allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
9+
#![allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
10+
1111
fn main() {
1212
// Test clippy::cast_precision_loss
1313
let x0 = 1i32;
@@ -252,3 +252,11 @@ fn main() {
252252
}
253253
}
254254
}
255+
256+
fn avoid_subtract_overflow(q: u32) {
257+
let c = (q >> 16) as u8;
258+
c as usize;
259+
260+
let c = (q / 1000) as u8;
261+
c as usize;
262+
}

tests/ui/cast.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,5 +194,17 @@ error: casting `main::E10` to `u16` may truncate the value
194194
LL | let _ = self as u16;
195195
| ^^^^^^^^^^^
196196

197-
error: aborting due to 31 previous errors
197+
error: casting `u32` to `u8` may truncate the value
198+
--> $DIR/cast.rs:257:13
199+
|
200+
LL | let c = (q >> 16) as u8;
201+
| ^^^^^^^^^^^^^^^
202+
203+
error: casting `u32` to `u8` may truncate the value
204+
--> $DIR/cast.rs:260:13
205+
|
206+
LL | let c = (q / 1000) as u8;
207+
| ^^^^^^^^^^^^^^^^
208+
209+
error: aborting due to 33 previous errors
198210

0 commit comments

Comments
 (0)