]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/transmute/transmuting_null.rs
Auto merge of #99443 - jam1garner:mips-virt-feature, r=nagisa
[rust.git] / src / tools / clippy / clippy_lints / src / transmute / transmuting_null.rs
1 use clippy_utils::consts::{constant_context, Constant};
2 use clippy_utils::diagnostics::span_lint;
3 use clippy_utils::is_path_diagnostic_item;
4 use if_chain::if_chain;
5 use rustc_ast::LitKind;
6 use rustc_hir::{Expr, ExprKind};
7 use rustc_lint::LateContext;
8 use rustc_middle::ty::Ty;
9 use rustc_span::symbol::sym;
10
11 use super::TRANSMUTING_NULL;
12
13 const LINT_MSG: &str = "transmuting a known null pointer into a reference";
14
15 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, to_ty: Ty<'tcx>) -> bool {
16     if !to_ty.is_ref() {
17         return false;
18     }
19
20     // Catching transmute over constants that resolve to `null`.
21     let mut const_eval_context = constant_context(cx, cx.typeck_results());
22     if_chain! {
23         if let ExprKind::Path(ref _qpath) = arg.kind;
24         if let Some(Constant::RawPtr(x)) = const_eval_context.expr(arg);
25         if x == 0;
26         then {
27             span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
28             return true;
29         }
30     }
31
32     // Catching:
33     // `std::mem::transmute(0 as *const i32)`
34     if_chain! {
35         if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind;
36         if let ExprKind::Lit(ref lit) = inner_expr.kind;
37         if let LitKind::Int(0, _) = lit.node;
38         then {
39             span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
40             return true;
41         }
42     }
43
44     // Catching:
45     // `std::mem::transmute(std::ptr::null::<i32>())`
46     if_chain! {
47         if let ExprKind::Call(func1, []) = arg.kind;
48         if is_path_diagnostic_item(cx, func1, sym::ptr_null);
49         then {
50             span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
51             return true;
52         }
53     }
54
55     // FIXME:
56     // Also catch transmutations of variables which are known nulls.
57     // To do this, MIR const propagation seems to be the better tool.
58     // Whenever MIR const prop routines are more developed, this will
59     // become available. As of this writing (25/03/19) it is not yet.
60     false
61 }