@@ -9,6 +9,7 @@ mod transmute_ptr_to_ref;
99mod transmute_ref_to_ref;
1010mod transmute_undefined_repr;
1111mod transmutes_expressible_as_ptr_casts;
12+ mod transmuting_null;
1213mod unsound_collection_transmute;
1314mod useless_transmute;
1415mod utils;
@@ -386,6 +387,28 @@ declare_clippy_lint! {
386387 "transmute to or from a type with an undefined representation"
387388}
388389
390+ declare_clippy_lint ! {
391+ /// ### What it does
392+ /// Checks for transmute calls which would receive a null pointer.
393+ ///
394+ /// ### Why is this bad?
395+ /// Transmuting a null pointer is undefined behavior.
396+ ///
397+ /// ### Known problems
398+ /// Not all cases can be detected at the moment of this writing.
399+ /// For example, variables which hold a null pointer and are then fed to a `transmute`
400+ /// call, aren't detectable yet.
401+ ///
402+ /// ### Example
403+ /// ```rust
404+ /// let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };
405+ /// ```
406+ #[ clippy:: version = "1.35.0" ]
407+ pub TRANSMUTING_NULL ,
408+ correctness,
409+ "transmutes from a null pointer to a reference, which is undefined behavior"
410+ }
411+
389412pub struct Transmute {
390413 msrv : Option < RustcVersion > ,
391414}
@@ -404,6 +427,7 @@ impl_lint_pass!(Transmute => [
404427 UNSOUND_COLLECTION_TRANSMUTE ,
405428 TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS ,
406429 TRANSMUTE_UNDEFINED_REPR ,
430+ TRANSMUTING_NULL ,
407431] ) ;
408432impl Transmute {
409433 #[ must_use]
@@ -436,6 +460,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
436460
437461 let linted = wrong_transmute:: check( cx, e, from_ty, to_ty)
438462 | crosspointer_transmute:: check( cx, e, from_ty, to_ty)
463+ | transmuting_null:: check( cx, e, arg, to_ty)
439464 | transmute_ptr_to_ref:: check( cx, e, from_ty, to_ty, arg, path, self . msrv)
440465 | transmute_int_to_char:: check( cx, e, from_ty, to_ty, arg, const_context)
441466 | transmute_ref_to_ref:: check( cx, e, from_ty, to_ty, arg, const_context)
0 commit comments