mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
New lint: zst_offset
This commit is contained in:
parent
b4f1769734
commit
c21b198576
7 changed files with 67 additions and 2 deletions
|
@ -1273,4 +1273,5 @@ Released 2018-09-13
|
|||
[`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal
|
||||
[`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr
|
||||
[`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space
|
||||
[`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
|
||||
<!-- end autogenerated links to lint list -->
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
||||
|
||||
[There are 333 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||
[There are 334 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||
|
||||
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
||||
|
||||
|
|
|
@ -625,6 +625,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||
&methods::USELESS_ASREF,
|
||||
&methods::WRONG_PUB_SELF_CONVENTION,
|
||||
&methods::WRONG_SELF_CONVENTION,
|
||||
&methods::ZST_OFFSET,
|
||||
&minmax::MIN_MAX,
|
||||
&misc::CMP_NAN,
|
||||
&misc::CMP_OWNED,
|
||||
|
@ -1177,6 +1178,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||
LintId::of(&methods::UNNECESSARY_FOLD),
|
||||
LintId::of(&methods::USELESS_ASREF),
|
||||
LintId::of(&methods::WRONG_SELF_CONVENTION),
|
||||
LintId::of(&methods::ZST_OFFSET),
|
||||
LintId::of(&minmax::MIN_MAX),
|
||||
LintId::of(&misc::CMP_NAN),
|
||||
LintId::of(&misc::CMP_OWNED),
|
||||
|
@ -1498,6 +1500,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
|||
LintId::of(&methods::CLONE_DOUBLE_REF),
|
||||
LintId::of(&methods::TEMPORARY_CSTRING_AS_PTR),
|
||||
LintId::of(&methods::UNINIT_ASSUMED_INIT),
|
||||
LintId::of(&methods::ZST_OFFSET),
|
||||
LintId::of(&minmax::MIN_MAX),
|
||||
LintId::of(&misc::CMP_NAN),
|
||||
LintId::of(&misc::FLOAT_CMP),
|
||||
|
|
|
@ -1065,6 +1065,23 @@ declare_clippy_lint! {
|
|||
"`.chcked_add/sub(x).unwrap_or(MAX/MIN)`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to
|
||||
/// zero-sized types
|
||||
///
|
||||
/// **Why is this bad?** This is a no-op, and likely unintended
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// unsafe { (&() as *const ()).offest(1) };
|
||||
/// ```
|
||||
pub ZST_OFFSET,
|
||||
correctness,
|
||||
"Check for offset calculations on raw pointers to zero-sized types"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Methods => [
|
||||
OPTION_UNWRAP_USED,
|
||||
RESULT_UNWRAP_USED,
|
||||
|
@ -1109,6 +1126,7 @@ declare_lint_pass!(Methods => [
|
|||
SUSPICIOUS_MAP,
|
||||
UNINIT_ASSUMED_INIT,
|
||||
MANUAL_SATURATING_ARITHMETIC,
|
||||
ZST_OFFSET,
|
||||
]);
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
|
||||
|
@ -1167,6 +1185,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
|
|||
| ["unwrap_or", arith @ "checked_mul"] => {
|
||||
manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..])
|
||||
},
|
||||
["add"] | ["offset"] | ["sub"] | ["wrapping_offset"] | ["wrapping_add"] | ["wrapping_sub"] => {
|
||||
check_pointer_offset(cx, expr, arg_lists[0])
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
|
@ -3063,3 +3084,15 @@ fn contains_return(expr: &hir::Expr) -> bool {
|
|||
visitor.visit_expr(expr);
|
||||
visitor.found
|
||||
}
|
||||
|
||||
fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) {
|
||||
if_chain! {
|
||||
if args.len() == 2;
|
||||
if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables.expr_ty(&args[0]).kind;
|
||||
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty));
|
||||
if layout.is_zst();
|
||||
then {
|
||||
span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ pub use lint::Lint;
|
|||
pub use lint::LINT_LEVELS;
|
||||
|
||||
// begin lint list, do not remove this comment, it’s used in `update_lints`
|
||||
pub const ALL_LINTS: [Lint; 333] = [
|
||||
pub const ALL_LINTS: [Lint; 334] = [
|
||||
Lint {
|
||||
name: "absurd_extreme_comparisons",
|
||||
group: "correctness",
|
||||
|
@ -2338,5 +2338,12 @@ pub const ALL_LINTS: [Lint; 333] = [
|
|||
deprecation: None,
|
||||
module: "unicode",
|
||||
},
|
||||
Lint {
|
||||
name: "zst_offset",
|
||||
group: "correctness",
|
||||
desc: "Check for offset calculations on raw pointers to zero-sized types",
|
||||
deprecation: None,
|
||||
module: "methods",
|
||||
},
|
||||
];
|
||||
// end lint list, do not remove this comment, it’s used in `update_lints`
|
||||
|
|
12
tests/ui/zero_offset.rs
Normal file
12
tests/ui/zero_offset.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
fn main() {
|
||||
unsafe {
|
||||
let x = &() as *const ();
|
||||
x.offset(0);
|
||||
x.wrapping_add(0);
|
||||
x.sub(0);
|
||||
x.wrapping_sub(0);
|
||||
|
||||
let y = &1 as *const u8;
|
||||
y.offset(0);
|
||||
}
|
||||
}
|
9
tests/ui/zero_offset.stderr
Normal file
9
tests/ui/zero_offset.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
error[E0606]: casting `&i32` as `*const u8` is invalid
|
||||
--> $DIR/zero_offset.rs:9:17
|
||||
|
|
||||
LL | let y = &1 as *const u8;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0606`.
|
Loading…
Reference in a new issue