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
;
9 use super::TRANSMUTE_NULL_TO_FN
;
11 fn lint_expr(cx
: &LateContext
<'_
>, expr
: &Expr
<'_
>) {
16 "transmuting a known null pointer into a function pointer",
18 diag
.span_label(expr
.span
, "this transmute results in undefined behavior");
20 "try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value"
26 pub(super) fn check
<'tcx
>(cx
: &LateContext
<'tcx
>, expr
: &'tcx Expr
<'_
>, arg
: &'tcx Expr
<'_
>, to_ty
: Ty
<'tcx
>) -> bool
{
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), _
))) =>
42 // `std::mem::transmute(0 as *const i32)`
43 ExprKind
::Cast(inner_expr
, _cast_ty
) if is_integer_literal(inner_expr
, 0) => {
49 // `std::mem::transmute(std::ptr::null::<i32>())`
50 ExprKind
::Call(func1
, []) if is_path_diagnostic_item(cx
, func1
, sym
::ptr_null
) => {
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.