Auto merge of #12451 - Jacherr:issue-12391, r=llogiq
new restriction lint: `integer_division_remainder_used` Fixes https://github.com/rust-lang/rust-clippy/issues/12391 Introduces a restriction lint which disallows the use of `/` and `%` operators on any `Int` or `Uint` types (i.e., any that use the default `Div` or `Rem` trait implementations). Custom implementations of these traits are ignored. ---- changelog: Add new restriction lint [`integer_division_remainder_used`]
This commit is contained in:
commit
e9a50f2859
@ -5281,6 +5281,7 @@ Released 2018-09-13
|
||||
[`int_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#int_plus_one
|
||||
[`integer_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_arithmetic
|
||||
[`integer_division`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division
|
||||
[`integer_division_remainder_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division_remainder_used
|
||||
[`into_iter_on_array`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_array
|
||||
[`into_iter_on_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_ref
|
||||
[`into_iter_without_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_without_iter
|
||||
|
@ -236,6 +236,7 @@
|
||||
crate::instant_subtraction::MANUAL_INSTANT_ELAPSED_INFO,
|
||||
crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO,
|
||||
crate::int_plus_one::INT_PLUS_ONE_INFO,
|
||||
crate::integer_division_remainder_used::INTEGER_DIVISION_REMAINDER_USED_INFO,
|
||||
crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
|
||||
crate::item_name_repetitions::ENUM_VARIANT_NAMES_INFO,
|
||||
crate::item_name_repetitions::MODULE_INCEPTION_INFO,
|
||||
|
50
clippy_lints/src/integer_division_remainder_used.rs
Normal file
50
clippy_lints/src/integer_division_remainder_used.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::BinOpKind;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for the usage of division (/) and remainder (%) operations
|
||||
/// when performed on any integer types using the default Div and Rem trait implementations.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// In cryptographic contexts, division can result in timing sidechannel vulnerabilities,
|
||||
/// and needs to be replaced with constant-time code instead (e.g. Barrett reduction).
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// let my_div = 10 / 2;
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// let my_div = 10 >> 1;
|
||||
/// ```
|
||||
#[clippy::version = "1.78.0"]
|
||||
pub INTEGER_DIVISION_REMAINDER_USED,
|
||||
restriction,
|
||||
"use of disallowed default division and remainder operations"
|
||||
}
|
||||
|
||||
declare_lint_pass!(IntegerDivisionRemainderUsed => [INTEGER_DIVISION_REMAINDER_USED]);
|
||||
|
||||
impl LateLintPass<'_> for IntegerDivisionRemainderUsed {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
if let ExprKind::Binary(op, lhs, rhs) = &expr.kind
|
||||
&& let BinOpKind::Div | BinOpKind::Rem = op.node
|
||||
&& let lhs_ty = cx.typeck_results().expr_ty(lhs)
|
||||
&& let rhs_ty = cx.typeck_results().expr_ty(rhs)
|
||||
&& let ty::Int(_) | ty::Uint(_) = lhs_ty.peel_refs().kind()
|
||||
&& let ty::Int(_) | ty::Uint(_) = rhs_ty.peel_refs().kind()
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
INTEGER_DIVISION_REMAINDER_USED,
|
||||
expr.span.source_callsite(),
|
||||
&format!("use of {} has been disallowed in this context", op.node.as_str()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -172,6 +172,7 @@
|
||||
mod inline_fn_without_body;
|
||||
mod instant_subtraction;
|
||||
mod int_plus_one;
|
||||
mod integer_division_remainder_used;
|
||||
mod invalid_upcast_comparisons;
|
||||
mod item_name_repetitions;
|
||||
mod items_after_statements;
|
||||
@ -1124,6 +1125,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
||||
store.register_late_pass(|_| Box::new(assigning_clones::AssigningClones));
|
||||
store.register_late_pass(|_| Box::new(zero_repeat_side_effects::ZeroRepeatSideEffects));
|
||||
store.register_late_pass(|_| Box::new(manual_unwrap_or_default::ManualUnwrapOrDefault));
|
||||
store.register_late_pass(|_| Box::new(integer_division_remainder_used::IntegerDivisionRemainderUsed));
|
||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||
}
|
||||
|
||||
|
41
tests/ui/integer_division_remainder_used.rs
Normal file
41
tests/ui/integer_division_remainder_used.rs
Normal file
@ -0,0 +1,41 @@
|
||||
#![warn(clippy::integer_division_remainder_used)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(clippy::op_ref)]
|
||||
|
||||
struct CustomOps(pub i32);
|
||||
impl std::ops::Div for CustomOps {
|
||||
type Output = Self;
|
||||
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
impl std::ops::Rem for CustomOps {
|
||||
type Output = Self;
|
||||
|
||||
fn rem(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 % rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// should trigger
|
||||
let a = 10;
|
||||
let b = 5;
|
||||
let c = a / b;
|
||||
let d = a % b;
|
||||
let e = &a / b;
|
||||
let f = a % &b;
|
||||
let g = &a / &b;
|
||||
let h = &10 % b;
|
||||
let i = a / &4;
|
||||
|
||||
// should not trigger on custom Div and Rem
|
||||
let w = CustomOps(3);
|
||||
let x = CustomOps(4);
|
||||
let y = w / x;
|
||||
|
||||
let w = CustomOps(3);
|
||||
let x = CustomOps(4);
|
||||
let z = w % x;
|
||||
}
|
59
tests/ui/integer_division_remainder_used.stderr
Normal file
59
tests/ui/integer_division_remainder_used.stderr
Normal file
@ -0,0 +1,59 @@
|
||||
error: use of / has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:10:14
|
||||
|
|
||||
LL | Self(self.0 / rhs.0)
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::integer-division-remainder-used` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::integer_division_remainder_used)]`
|
||||
|
||||
error: use of % has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:17:14
|
||||
|
|
||||
LL | Self(self.0 % rhs.0)
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: use of / has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:25:13
|
||||
|
|
||||
LL | let c = a / b;
|
||||
| ^^^^^
|
||||
|
||||
error: use of % has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:26:13
|
||||
|
|
||||
LL | let d = a % b;
|
||||
| ^^^^^
|
||||
|
||||
error: use of / has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:27:13
|
||||
|
|
||||
LL | let e = &a / b;
|
||||
| ^^^^^^
|
||||
|
||||
error: use of % has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:28:13
|
||||
|
|
||||
LL | let f = a % &b;
|
||||
| ^^^^^^
|
||||
|
||||
error: use of / has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:29:13
|
||||
|
|
||||
LL | let g = &a / &b;
|
||||
| ^^^^^^^
|
||||
|
||||
error: use of % has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:30:13
|
||||
|
|
||||
LL | let h = &10 % b;
|
||||
| ^^^^^^^
|
||||
|
||||
error: use of / has been disallowed in this context
|
||||
--> tests/ui/integer_division_remainder_used.rs:31:13
|
||||
|
|
||||
LL | let i = a / &4;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user