@@ -3,6 +3,7 @@ mod transmute_float_to_int;
33mod transmute_int_to_bool;
44mod transmute_int_to_char;
55mod transmute_int_to_float;
6+ mod transmute_null_to_fn;
67mod transmute_num_to_bytes;
78mod transmute_ptr_to_ptr;
89mod transmute_ptr_to_ref;
@@ -409,6 +410,34 @@ declare_clippy_lint! {
409410 "transmutes from a null pointer to a reference, which is undefined behavior"
410411}
411412
413+ declare_clippy_lint ! {
414+ /// ### What it does
415+ /// Checks for null function pointer creation through transmute.
416+ ///
417+ /// ### Why is this bad?
418+ /// Creating a null function pointer is undefined behavior.
419+ ///
420+ /// More info: https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimization
421+ ///
422+ /// ### Known problems
423+ /// Not all cases can be detected at the moment of this writing.
424+ /// For example, variables which hold a null pointer and are then fed to a `transmute`
425+ /// call, aren't detectable yet.
426+ ///
427+ /// ### Example
428+ /// ```rust
429+ /// let null_fn: fn() = unsafe { std::mem::transmute( std::ptr::null() ) };
430+ /// ```
431+ /// Use instead:
432+ /// ```rust
433+ /// let null_fn: Option<fn()> = None;
434+ /// ```
435+ #[ clippy:: version = "1.67.0" ]
436+ pub TRANSMUTE_NULL_TO_FN ,
437+ correctness,
438+ "transmute results in a null function pointer, which is undefined behavior"
439+ }
440+
412441pub struct Transmute {
413442 msrv : Msrv ,
414443}
@@ -428,6 +457,7 @@ impl_lint_pass!(Transmute => [
428457 TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS ,
429458 TRANSMUTE_UNDEFINED_REPR ,
430459 TRANSMUTING_NULL ,
460+ TRANSMUTE_NULL_TO_FN ,
431461] ) ;
432462impl Transmute {
433463 #[ must_use]
@@ -461,6 +491,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
461491 let linted = wrong_transmute:: check( cx, e, from_ty, to_ty)
462492 | crosspointer_transmute:: check( cx, e, from_ty, to_ty)
463493 | transmuting_null:: check( cx, e, arg, to_ty)
494+ | transmute_null_to_fn:: check( cx, e, arg, to_ty)
464495 | transmute_ptr_to_ref:: check( cx, e, from_ty, to_ty, arg, path, & self . msrv)
465496 | transmute_int_to_char:: check( cx, e, from_ty, to_ty, arg, const_context)
466497 | transmute_ref_to_ref:: check( cx, e, from_ty, to_ty, arg, const_context)
0 commit comments