diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index c9c404c1740b..2896e2b7adaf 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -201,6 +201,24 @@ declare_lint! { "using 0 as *{const, mut} T" } +/// **What it does:** Catch casts from `1` to some pointer type +/// +/// **Why is this bad?** This generally means a dangling pointer and is better expressed as +/// {`std`, `core`}`::ptr::`{`dangling`, `dangling_mut`}. +/// +/// **Known problems:** None. +/// +/// **Example:** +/// +/// ```rust +/// 1 as *const u32 +/// ``` +declare_lint! { + pub DANGLING_PTR, + Allow, + "using 1 as *{const, mut} T" +} + /// **What it does:** Checks for (in-)equality comparisons on floating-point /// value and constant, except in functions called `*eq*` (which probably /// implement equality for a type involving floats). @@ -237,6 +255,7 @@ impl LintPass for Pass { USED_UNDERSCORE_BINDING, SHORT_CIRCUIT_STATEMENT, ZERO_PTR, + DANGLING_PTR, FLOAT_CMP_CONST ) } @@ -628,14 +647,21 @@ fn check_cast(cx: &LateContext, span: Span, e: &Expr, ty: &Ty) { if let TyPtr(MutTy { mutbl, .. }) = ty.node; if let ExprLit(ref lit) = e.node; if let LitKind::Int(value, ..) = lit.node; - if value == 0; if !in_constant(cx, e.id); then { - let msg = match mutbl { - Mutability::MutMutable => "`0 as *mut _` detected. Consider using `ptr::null_mut()`", - Mutability::MutImmutable => "`0 as *const _` detected. Consider using `ptr::null()`", - }; - span_lint(cx, ZERO_PTR, span, msg); + if value == 0 { + let msg = match mutbl { + Mutability::MutMutable => "`0 as *mut _` detected. Consider using `ptr::null_mut()`", + Mutability::MutImmutable => "`0 as *const _` detected. Consider using `ptr::null()`", + }; + span_lint(cx, ZERO_PTR, span, msg); + } else if value == 1 { + let msg = match mutbl { + Mutability::MutMutable => "`1 as *mut _` detected. Consider using `ptr::dangling_mut()`", + Mutability::MutImmutable => "`1 as *const _` detected. Consider using `ptr::dangling()`", + }; + span_lint(cx, DANGLING_PTR, span, msg); + } } } } diff --git a/tests/ui/dangling_ptr.rs b/tests/ui/dangling_ptr.rs new file mode 100644 index 000000000000..3795cd6a8bd8 --- /dev/null +++ b/tests/ui/dangling_ptr.rs @@ -0,0 +1,10 @@ +#![warn(dangling_ptr)] + +#[allow(unused_variables)] +fn main() { + let x = 1 as *const usize; + let y = 1 as *mut f64; + + let z = 1; + let z = z as *const usize; // this is currently not caught +} diff --git a/tests/ui/dangling_ptr.stderr b/tests/ui/dangling_ptr.stderr new file mode 100644 index 000000000000..b6b67dd648bf --- /dev/null +++ b/tests/ui/dangling_ptr.stderr @@ -0,0 +1,14 @@ +error: `1 as *const _` detected. Consider using `ptr::dangling()` + --> $DIR/dangling_ptr.rs:5:13 + | +5 | let x = 1 as *const usize; + | ^^^^^^^^^^^^^^^^^ + | + = note: `-D dangling-ptr` implied by `-D warnings` + +error: `1 as *mut _` detected. Consider using `ptr::dangling_mut()` + --> $DIR/dangling_ptr.rs:6:13 + | +6 | let y = 1 as *mut f64; + | ^^^^^^^^^^^^^ +