Disallow bit-shifting in integer_arithmetic lint

With this change, the lint checks all operations that are defined as
being capable of overflow in the Rust Reference.
This commit is contained in:
Michael Sproul 2020-04-13 13:11:19 +10:00
parent e29d550565
commit 23df4a0183
No known key found for this signature in database
GPG key ID: 77B1309D2E54E914
4 changed files with 48 additions and 22 deletions

View file

@ -6,11 +6,17 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
declare_clippy_lint! { declare_clippy_lint! {
/// **What it does:** Checks for plain integer arithmetic. /// **What it does:** Checks for integer arithmetic operations which could overflow or panic.
/// ///
/// **Why is this bad?** This is only checked against overflow in debug builds. /// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable
/// In some applications one wants explicitly checked, wrapping or saturating /// of overflowing according to the [Rust
/// arithmetic. /// Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
/// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is
/// attempted.
///
/// **Why is this bad?** Integer overflow will trigger a panic in debug builds or will wrap in
/// release mode. Division by zero will cause a panic in either mode. In some applications one
/// wants explicitly checked, wrapping or saturating arithmetic.
/// ///
/// **Known problems:** None. /// **Known problems:** None.
/// ///
@ -21,7 +27,7 @@ declare_clippy_lint! {
/// ``` /// ```
pub INTEGER_ARITHMETIC, pub INTEGER_ARITHMETIC,
restriction, restriction,
"any integer arithmetic statement" "any integer arithmetic expression which could overflow or panic"
} }
declare_clippy_lint! { declare_clippy_lint! {
@ -71,8 +77,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
| hir::BinOpKind::BitAnd | hir::BinOpKind::BitAnd
| hir::BinOpKind::BitOr | hir::BinOpKind::BitOr
| hir::BinOpKind::BitXor | hir::BinOpKind::BitXor
| hir::BinOpKind::Shl
| hir::BinOpKind::Shr
| hir::BinOpKind::Eq | hir::BinOpKind::Eq
| hir::BinOpKind::Lt | hir::BinOpKind::Lt
| hir::BinOpKind::Le | hir::BinOpKind::Le

View file

@ -846,7 +846,7 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
Lint { Lint {
name: "integer_arithmetic", name: "integer_arithmetic",
group: "restriction", group: "restriction",
desc: "any integer arithmetic statement", desc: "any integer arithmetic expression which could overflow or panic",
deprecation: None, deprecation: None,
module: "arithmetic", module: "arithmetic",
}, },

View file

@ -17,6 +17,8 @@ fn main() {
i / 2; // no error, this is part of the expression in the preceding line i / 2; // no error, this is part of the expression in the preceding line
i - 2 + 2 - i; i - 2 + 2 - i;
-i; -i;
i >> 1;
i << 1;
// no error, overflows are checked by `overflowing_literals` // no error, overflows are checked by `overflowing_literals`
-1; -1;
@ -25,18 +27,16 @@ fn main() {
i & 1; // no wrapping i & 1; // no wrapping
i | 1; i | 1;
i ^ 1; i ^ 1;
i >> 1;
i << 1;
i += 1; i += 1;
i -= 1; i -= 1;
i *= 2; i *= 2;
i /= 2; i /= 2;
i %= 2; i %= 2;
// no errors
i <<= 3; i <<= 3;
i >>= 2; i >>= 2;
// no errors
i |= 1; i |= 1;
i &= 1; i &= 1;
i ^= i; i ^= i;
@ -72,8 +72,6 @@ fn main() {
1 + 1 1 + 1
}; };
} }
} }
// warn on references as well! (#5328) // warn on references as well! (#5328)

View file

@ -31,6 +31,18 @@ error: integer arithmetic detected
LL | -i; LL | -i;
| ^^ | ^^
error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:20:5
|
LL | i >> 1;
| ^^^^^^
error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:21:5
|
LL | i << 1;
| ^^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:31:5 --> $DIR/integer_arithmetic.rs:31:5
| |
@ -62,46 +74,58 @@ LL | i %= 2;
| ^^^^^^ | ^^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:81:5 --> $DIR/integer_arithmetic.rs:36:5
|
LL | i <<= 3;
| ^^^^^^^
error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:37:5
|
LL | i >>= 2;
| ^^^^^^^
error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:79:5
| |
LL | 3 + &1; LL | 3 + &1;
| ^^^^^^ | ^^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:82:5 --> $DIR/integer_arithmetic.rs:80:5
| |
LL | &3 + 1; LL | &3 + 1;
| ^^^^^^ | ^^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:83:5 --> $DIR/integer_arithmetic.rs:81:5
| |
LL | &3 + &1; LL | &3 + &1;
| ^^^^^^^ | ^^^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:88:5 --> $DIR/integer_arithmetic.rs:86:5
| |
LL | a + x LL | a + x
| ^^^^^ | ^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:92:5 --> $DIR/integer_arithmetic.rs:90:5
| |
LL | x + y LL | x + y
| ^^^^^ | ^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:96:5 --> $DIR/integer_arithmetic.rs:94:5
| |
LL | x + y LL | x + y
| ^^^^^ | ^^^^^
error: integer arithmetic detected error: integer arithmetic detected
--> $DIR/integer_arithmetic.rs:100:5 --> $DIR/integer_arithmetic.rs:98:5
| |
LL | (&x + &y) LL | (&x + &y)
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to 17 previous errors error: aborting due to 21 previous errors