]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / transmute / transmute_null_to_fn.rs
1 use clippy_utils::consts::{constant, Constant};
2 use clippy_utils::diagnostics::span_lint_and_then;
3 use clippy_utils::{is_integer_literal, is_path_diagnostic_item};
4 use rustc_hir::{Expr, ExprKind};
5 use rustc_lint::LateContext;
6 use rustc_middle::ty::Ty;
7 use rustc_span::symbol::sym;
8
9 use super::TRANSMUTE_NULL_TO_FN;
10
11 fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
12 span_lint_and_then(
13 cx,
14 TRANSMUTE_NULL_TO_FN,
15 expr.span,
16 "transmuting a known null pointer into a function pointer",
17 |diag| {
18 diag.span_label(expr.span, "this transmute results in undefined behavior");
19 diag.help(
20 "try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value"
21 );
22 },
23 );
24 }
25
26 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, to_ty: Ty<'tcx>) -> bool {
27 if !to_ty.is_fn() {
28 return false;
29 }
30
31 match arg.kind {
32 // Catching:
33 // transmute over constants that resolve to `null`.
34 ExprKind::Path(ref _qpath)
35 if matches!(constant(cx, cx.typeck_results(), arg), Some((Constant::RawPtr(0), _))) =>
36 {
37 lint_expr(cx, expr);
38 true
39 },
40
41 // Catching:
42 // `std::mem::transmute(0 as *const i32)`
43 ExprKind::Cast(inner_expr, _cast_ty) if is_integer_literal(inner_expr, 0) => {
44 lint_expr(cx, expr);
45 true
46 },
47
48 // Catching:
49 // `std::mem::transmute(std::ptr::null::<i32>())`
50 ExprKind::Call(func1, []) if is_path_diagnostic_item(cx, func1, sym::ptr_null) => {
51 lint_expr(cx, expr);
52 true
53 },
54
55 _ => {
56 // FIXME:
57 // Also catch transmutations of variables which are known nulls.
58 // To do this, MIR const propagation seems to be the better tool.
59 // Whenever MIR const prop routines are more developed, this will
60 // become available. As of this writing (25/03/19) it is not yet.
61 false
62 },
63 }
64 }