New zero_ptr lint.

This fixes #1047. I did not bother to add a full suggestion,
because replacing with `std::ptr::null()` may still lead to
inference failures.
This commit is contained in:
Andre Bogus 2017-02-21 04:36:59 +01:00
parent 8a227c7577
commit 2f7babba82
7 changed files with 71 additions and 4 deletions

View File

@ -1,6 +1,7 @@
# Change Log
All notable changes to this project will be documented in this file.
* New [`zero_ptr`] lint
* New [`never_loop`] lint
* New [`mut_from_ref`] lint
@ -472,5 +473,6 @@ All notable changes to this project will be documented in this file.
[`wrong_transmute`]: https://github.com/Manishearth/rust-clippy/wiki#wrong_transmute
[`zero_divided_by_zero`]: https://github.com/Manishearth/rust-clippy/wiki#zero_divided_by_zero
[`zero_prefixed_literal`]: https://github.com/Manishearth/rust-clippy/wiki#zero_prefixed_literal
[`zero_ptr`]: https://github.com/Manishearth/rust-clippy/wiki#zero_ptr
[`zero_width_space`]: https://github.com/Manishearth/rust-clippy/wiki#zero_width_space
<!-- end autogenerated links to wiki -->

View File

@ -180,7 +180,7 @@ transparently:
## Lints
There are 191 lints included in this crate:
There are 192 lints included in this crate:
name | default | triggers on
-----------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------
@ -374,6 +374,7 @@ name
[wrong_transmute](https://github.com/Manishearth/rust-clippy/wiki#wrong_transmute) | warn | transmutes that are confusing at best, undefined behaviour at worst and always useless
[zero_divided_by_zero](https://github.com/Manishearth/rust-clippy/wiki#zero_divided_by_zero) | warn | usage of `0.0 / 0.0` to obtain NaN instead of std::f32::NaN or std::f64::NaN
[zero_prefixed_literal](https://github.com/Manishearth/rust-clippy/wiki#zero_prefixed_literal) | warn | integer literals starting with `0`
[zero_ptr](https://github.com/Manishearth/rust-clippy/wiki#zero_ptr) | warn | using 0 as *{const, mut} T
[zero_width_space](https://github.com/Manishearth/rust-clippy/wiki#zero_width_space) | deny | using a zero-width space in a string literal, which is confusing
More to come, please [file an issue](https://github.com/Manishearth/rust-clippy/issues) if you have ideas!

View File

@ -450,6 +450,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
misc_early::REDUNDANT_CLOSURE_CALL,
misc_early::UNNEEDED_FIELD_PATTERN,
misc_early::ZERO_PREFIXED_LITERAL,
misc_early::ZERO_PTR,
mut_reference::UNNECESSARY_MUT_PASSED,
mutex_atomic::MUTEX_ATOMIC,
needless_bool::BOOL_COMPARISON,

View File

@ -162,6 +162,23 @@ declare_lint! {
"shadowing a builtin type"
}
/// **What it does:** Catch casts from `0` to some pointer type
///
/// **Why is this bad?** This generally means `null` and is better expressed as
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// ß as *const u32
/// ```
declare_lint! {
pub ZERO_PTR,
Warn,
"using 0 as *{const, mut} T"
}
#[derive(Copy, Clone)]
pub struct MiscEarly;
@ -175,7 +192,8 @@ impl LintPass for MiscEarly {
MIXED_CASE_HEX_LITERALS,
UNSEPARATED_LITERAL_SUFFIX,
ZERO_PREFIXED_LITERAL,
BUILTIN_TYPE_SHADOW)
BUILTIN_TYPE_SHADOW,
ZERO_PTR)
}
}
@ -363,6 +381,9 @@ impl EarlyLintPass for MiscEarly {
}
}}
},
ExprKind::Cast(ref e, ref ty) => {
check_cast(cx, expr.span, e, ty);
},
_ => (),
}
}
@ -391,3 +412,18 @@ impl EarlyLintPass for MiscEarly {
}
}
}
fn check_cast(cx: &EarlyContext, span: Span, e: &Expr, ty: &Ty) {
if_let_chain! {[
let TyKind::Ptr(MutTy { mutbl, .. }) = ty.node,
let ExprKind::Lit(ref lit) = e.node,
let LitKind::Int(value, ..) = lit.node,
value == 0
], {
let msg = match mutbl {
Mutability::Mutable => "`0 as *mut _` detected. Consider using `ptr::null_mut()`",
Mutability::Immutable => "`0 as *const _` detected. Consider using `ptr::null()`",
};
span_lint(cx, ZERO_PTR, span, msg);
}}
}

View File

@ -91,7 +91,7 @@ fn issue1231() {
bar: &'a T,
}
let raw = 0 as *const i32;
let raw = 42 as *const i32;
let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
@ -103,7 +103,7 @@ fn issue1231() {
type Bar<'a> = &'a u8;
let raw = 0 as *const i32;
let raw = 42 as *const i32;
unsafe { std::mem::transmute::<_, Bar>(raw) };

11
tests/ui/zero_ptr.rs Normal file
View File

@ -0,0 +1,11 @@
#![feature(plugin)]
#![plugin(clippy)]
#[allow(unused_variables)]
fn main() {
let x = 0 as *const usize;
let y = 0 as *mut f64;
let z = 0;
let z = z as *const usize; // this is currently not caught
}

16
tests/ui/zero_ptr.stderr Normal file
View File

@ -0,0 +1,16 @@
warning: `0 as *const _` detected. Consider using `ptr::null()`
--> $DIR/zero_ptr.rs:6:13
|
6 | let x = 0 as *const usize;
| ^^^^^^^^^^^^^^^^^
|
= note: #[warn(zero_ptr)] on by default
warning: `0 as *mut _` detected. Consider using `ptr::null_mut()`
--> $DIR/zero_ptr.rs:7:13
|
7 | let y = 0 as *mut f64;
| ^^^^^^^^^^^^^
|
= note: #[warn(zero_ptr)] on by default