about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/messages.ftl22
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs26
-rw-r--r--compiler/rustc_lint/src/ptr_nulls.rs128
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs44
-rw-r--r--compiler/rustc_lint/src/utils.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/deprecated_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs73
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-1782.rs2
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed66
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs66
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr136
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed79
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs79
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr136
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed1
-rw-r--r--src/tools/clippy/tests/ui/rename.rs1
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr30
-rw-r--r--tests/ui/lint/invalid_null_args.rs136
-rw-r--r--tests/ui/lint/invalid_null_args.stderr330
-rw-r--r--tests/ui/precondition-checks/copy-nonoverlapping.rs2
-rw-r--r--tests/ui/precondition-checks/copy.rs2
-rw-r--r--tests/ui/precondition-checks/read_volatile.rs2
-rw-r--r--tests/ui/precondition-checks/replace.rs2
-rw-r--r--tests/ui/precondition-checks/slice-from-raw-parts-mut.rs2
-rw-r--r--tests/ui/precondition-checks/slice-from-raw-parts.rs2
-rw-r--r--tests/ui/precondition-checks/swap-nonoverlapping.rs2
-rw-r--r--tests/ui/precondition-checks/write_volatile.rs2
-rw-r--r--tests/ui/precondition-checks/zero-size-null.rs2
30 files changed, 713 insertions, 719 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 0a3eb434d3f..782d328a951 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -456,6 +456,10 @@ lint_invalid_nan_comparisons_eq_ne = incorrect NaN comparison, NaN cannot be dir
 
 lint_invalid_nan_comparisons_lt_le_gt_ge = incorrect NaN comparison, NaN is not orderable
 
+lint_invalid_null_arguments = calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+    .origin = null pointer originates from here
+    .doc = for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
 lint_invalid_reference_casting_assign_to_ref = assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
     .label = casting happened here
 
@@ -680,15 +684,6 @@ lint_private_extern_crate_reexport = extern crate `{$ident}` is private and cann
 lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` in this scope
     .label = names from parent modules are not accessible without an explicit import
 
-lint_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false
-    .help = wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
-    .label = expression has type `{$orig_ty}`
-
-lint_ptr_null_checks_fn_ret = returned pointer of `{$fn_name}` call is never null, so checking it for null will always return false
-
-lint_ptr_null_checks_ref = references are not nullable, so checking them for null will always return false
-    .label = expression has type `{$orig_ty}`
-
 lint_query_instability = using `{$query}` can result in unstable query results
     .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
@@ -981,6 +976,15 @@ lint_unused_result = unused result of type `{$ty}`
 
 lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
 
+lint_useless_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false
+    .help = wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
+    .label = expression has type `{$orig_ty}`
+
+lint_useless_ptr_null_checks_fn_ret = returned pointer of `{$fn_name}` call is never null, so checking it for null will always return false
+
+lint_useless_ptr_null_checks_ref = references are not nullable, so checking them for null will always return false
+    .label = expression has type `{$orig_ty}`
+
 lint_uses_power_alignment = repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
 
 lint_variant_size_differences =
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index cd474f1b7db..25878c7ac81 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -80,6 +80,7 @@ mod types;
 mod unit_bindings;
 mod unqualified_local_imports;
 mod unused;
+mod utils;
 
 use async_closures::AsyncClosureUsage;
 use async_fn_in_trait::AsyncFnInTrait;
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 036d68d13fa..55d010e6d34 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -591,24 +591,40 @@ pub(crate) struct ExpectationNote {
 
 // ptr_nulls.rs
 #[derive(LintDiagnostic)]
-pub(crate) enum PtrNullChecksDiag<'a> {
-    #[diag(lint_ptr_null_checks_fn_ptr)]
-    #[help(lint_help)]
+pub(crate) enum UselessPtrNullChecksDiag<'a> {
+    #[diag(lint_useless_ptr_null_checks_fn_ptr)]
+    #[help]
     FnPtr {
         orig_ty: Ty<'a>,
         #[label]
         label: Span,
     },
-    #[diag(lint_ptr_null_checks_ref)]
+    #[diag(lint_useless_ptr_null_checks_ref)]
     Ref {
         orig_ty: Ty<'a>,
         #[label]
         label: Span,
     },
-    #[diag(lint_ptr_null_checks_fn_ret)]
+    #[diag(lint_useless_ptr_null_checks_fn_ret)]
     FnRet { fn_name: Ident },
 }
 
+#[derive(LintDiagnostic)]
+pub(crate) enum InvalidNullArgumentsDiag {
+    #[diag(lint_invalid_null_arguments)]
+    #[help(lint_doc)]
+    NullPtrInline {
+        #[label(lint_origin)]
+        null_span: Span,
+    },
+    #[diag(lint_invalid_null_arguments)]
+    #[help(lint_doc)]
+    NullPtrThroughBinding {
+        #[note(lint_origin)]
+        null_span: Span,
+    },
+}
+
 // for_loops_over_fallibles.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_for_loops_over_fallibles)]
diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs
index 1489f9de819..826bce2c315 100644
--- a/compiler/rustc_lint/src/ptr_nulls.rs
+++ b/compiler/rustc_lint/src/ptr_nulls.rs
@@ -1,9 +1,11 @@
 use rustc_ast::LitKind;
 use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind};
+use rustc_middle::ty::RawPtr;
 use rustc_session::{declare_lint, declare_lint_pass};
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
-use crate::lints::PtrNullChecksDiag;
+use crate::lints::{InvalidNullArgumentsDiag, UselessPtrNullChecksDiag};
+use crate::utils::peel_casts;
 use crate::{LateContext, LateLintPass, LintContext};
 
 declare_lint! {
@@ -31,17 +33,40 @@ declare_lint! {
     "useless checking of non-null-typed pointer"
 }
 
-declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS]);
+declare_lint! {
+    /// The `invalid_null_arguments` lint checks for invalid usage of null pointers in arguments.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # use std::{slice, ptr};
+    /// // Undefined behavior
+    /// # let _slice: &[u8] =
+    /// unsafe { slice::from_raw_parts(ptr::null(), 0) };
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Calling methods whos safety invariants requires non-null ptr with a null pointer
+    /// is [Undefined Behavior](https://doc.rust-lang.org/reference/behavior-considered-undefined.html)!
+    INVALID_NULL_ARGUMENTS,
+    Deny,
+    "invalid null pointer in arguments"
+}
+
+declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS, INVALID_NULL_ARGUMENTS]);
 
 /// This function checks if the expression is from a series of consecutive casts,
 /// ie. `(my_fn as *const _ as *mut _).cast_mut()` and whether the original expression is either
 /// a fn ptr, a reference, or a function call whose definition is
 /// annotated with `#![rustc_never_returns_null_ptr]`.
 /// If this situation is present, the function returns the appropriate diagnostic.
-fn incorrect_check<'a, 'tcx: 'a>(
+fn useless_check<'a, 'tcx: 'a>(
     cx: &'a LateContext<'tcx>,
     mut e: &'a Expr<'a>,
-) -> Option<PtrNullChecksDiag<'tcx>> {
+) -> Option<UselessPtrNullChecksDiag<'tcx>> {
     let mut had_at_least_one_cast = false;
     loop {
         e = e.peel_blocks();
@@ -50,14 +75,14 @@ fn incorrect_check<'a, 'tcx: 'a>(
             && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr)
             && let Some(fn_name) = cx.tcx.opt_item_ident(def_id)
         {
-            return Some(PtrNullChecksDiag::FnRet { fn_name });
+            return Some(UselessPtrNullChecksDiag::FnRet { fn_name });
         } else if let ExprKind::Call(path, _args) = e.kind
             && let ExprKind::Path(ref qpath) = path.kind
             && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
             && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr)
             && let Some(fn_name) = cx.tcx.opt_item_ident(def_id)
         {
-            return Some(PtrNullChecksDiag::FnRet { fn_name });
+            return Some(UselessPtrNullChecksDiag::FnRet { fn_name });
         }
         e = if let ExprKind::Cast(expr, t) = e.kind
             && let TyKind::Ptr(_) = t.kind
@@ -73,9 +98,9 @@ fn incorrect_check<'a, 'tcx: 'a>(
         } else if had_at_least_one_cast {
             let orig_ty = cx.typeck_results().expr_ty(e);
             return if orig_ty.is_fn() {
-                Some(PtrNullChecksDiag::FnPtr { orig_ty, label: e.span })
+                Some(UselessPtrNullChecksDiag::FnPtr { orig_ty, label: e.span })
             } else if orig_ty.is_ref() {
-                Some(PtrNullChecksDiag::Ref { orig_ty, label: e.span })
+                Some(UselessPtrNullChecksDiag::Ref { orig_ty, label: e.span })
             } else {
                 None
             };
@@ -85,6 +110,25 @@ fn incorrect_check<'a, 'tcx: 'a>(
     }
 }
 
+/// Checks if the given expression is a null pointer (modulo casting)
+fn is_null_ptr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<Span> {
+    let (expr, _) = peel_casts(cx, expr);
+
+    if let ExprKind::Call(path, []) = expr.kind
+        && let ExprKind::Path(ref qpath) = path.kind
+        && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+        && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
+    {
+        (diag_item == sym::ptr_null || diag_item == sym::ptr_null_mut).then_some(expr.span)
+    } else if let ExprKind::Lit(spanned) = expr.kind
+        && let LitKind::Int(v, _) = spanned.node
+    {
+        (v == 0).then_some(expr.span)
+    } else {
+        None
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         match expr.kind {
@@ -97,12 +141,68 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
                         cx.tcx.get_diagnostic_name(def_id),
                         Some(sym::ptr_const_is_null | sym::ptr_is_null)
                     )
-                    && let Some(diag) = incorrect_check(cx, arg) =>
+                    && let Some(diag) = useless_check(cx, arg) =>
             {
                 cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
             }
 
             // Catching:
+            // <path>(arg...) where `arg` is null-ptr and `path` is a fn that expect non-null-ptr
+            ExprKind::Call(path, args)
+                if let ExprKind::Path(ref qpath) = path.kind
+                    && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+                    && let Some(diag_name) = cx.tcx.get_diagnostic_name(def_id) =>
+            {
+                // `arg` positions where null would cause U.B and whenever ZST are allowed.
+                //
+                // We should probably have a `rustc` attribute, but checking them is costly,
+                // maybe if we checked for null ptr first, it would be acceptable?
+                let (arg_indices, are_zsts_allowed): (&[_], _) = match diag_name {
+                    sym::ptr_read
+                    | sym::ptr_read_unaligned
+                    | sym::ptr_read_volatile
+                    | sym::ptr_replace
+                    | sym::ptr_write
+                    | sym::ptr_write_bytes
+                    | sym::ptr_write_unaligned
+                    | sym::ptr_write_volatile => (&[0], true),
+                    sym::slice_from_raw_parts | sym::slice_from_raw_parts_mut => (&[0], false),
+                    sym::ptr_copy
+                    | sym::ptr_copy_nonoverlapping
+                    | sym::ptr_swap
+                    | sym::ptr_swap_nonoverlapping => (&[0, 1], true),
+                    _ => return,
+                };
+
+                for &arg_idx in arg_indices {
+                    if let Some(arg) = args.get(arg_idx)
+                        && let Some(null_span) = is_null_ptr(cx, arg)
+                        && let Some(ty) = cx.typeck_results().expr_ty_opt(arg)
+                        && let RawPtr(ty, _mutbl) = ty.kind()
+                    {
+                        // If ZST are fine, don't lint on them
+                        let typing_env = cx.typing_env();
+                        if are_zsts_allowed
+                            && cx
+                                .tcx
+                                .layout_of(typing_env.as_query_input(*ty))
+                                .is_ok_and(|layout| layout.is_1zst())
+                        {
+                            break;
+                        }
+
+                        let diag = if arg.span.contains(null_span) {
+                            InvalidNullArgumentsDiag::NullPtrInline { null_span }
+                        } else {
+                            InvalidNullArgumentsDiag::NullPtrThroughBinding { null_span }
+                        };
+
+                        cx.emit_span_lint(INVALID_NULL_ARGUMENTS, expr.span, diag)
+                    }
+                }
+            }
+
+            // Catching:
             // (fn_ptr as *<const/mut> <ty>).is_null()
             ExprKind::MethodCall(_, receiver, _, _)
                 if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
@@ -110,18 +210,18 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
                         cx.tcx.get_diagnostic_name(def_id),
                         Some(sym::ptr_const_is_null | sym::ptr_is_null)
                     )
-                    && let Some(diag) = incorrect_check(cx, receiver) =>
+                    && let Some(diag) = useless_check(cx, receiver) =>
             {
                 cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag)
             }
 
             ExprKind::Binary(op, left, right) if matches!(op.node, BinOpKind::Eq) => {
                 let to_check: &Expr<'_>;
-                let diag: PtrNullChecksDiag<'_>;
-                if let Some(ddiag) = incorrect_check(cx, left) {
+                let diag: UselessPtrNullChecksDiag<'_>;
+                if let Some(ddiag) = useless_check(cx, left) {
                     to_check = right;
                     diag = ddiag;
-                } else if let Some(ddiag) = incorrect_check(cx, right) {
+                } else if let Some(ddiag) = useless_check(cx, right) {
                     to_check = left;
                     diag = ddiag;
                 } else {
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 7c6656f91c9..1d4d380cb68 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -6,6 +6,7 @@ use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 
 use crate::lints::InvalidReferenceCastingDiag;
+use crate::utils::peel_casts;
 use crate::{LateContext, LateLintPass, LintContext};
 
 declare_lint! {
@@ -235,46 +236,3 @@ fn is_cast_to_bigger_memory_layout<'tcx>(
         None
     }
 }
-
-fn peel_casts<'tcx>(cx: &LateContext<'tcx>, mut e: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, bool) {
-    let mut gone_trough_unsafe_cell_raw_get = false;
-
-    loop {
-        e = e.peel_blocks();
-        // <expr> as ...
-        e = if let ExprKind::Cast(expr, _) = e.kind {
-            expr
-        // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const()
-        } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
-            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
-            && matches!(
-                cx.tcx.get_diagnostic_name(def_id),
-                Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const)
-            )
-        {
-            expr
-        // ptr::from_ref(<expr>), UnsafeCell::raw_get(<expr>) or mem::transmute<_, _>(<expr>)
-        } else if let ExprKind::Call(path, [arg]) = e.kind
-            && let ExprKind::Path(ref qpath) = path.kind
-            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
-            && matches!(
-                cx.tcx.get_diagnostic_name(def_id),
-                Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute)
-            )
-        {
-            if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
-                gone_trough_unsafe_cell_raw_get = true;
-            }
-            arg
-        } else {
-            let init = cx.expr_or_init(e);
-            if init.hir_id != e.hir_id {
-                init
-            } else {
-                break;
-            }
-        };
-    }
-
-    (e, gone_trough_unsafe_cell_raw_get)
-}
diff --git a/compiler/rustc_lint/src/utils.rs b/compiler/rustc_lint/src/utils.rs
new file mode 100644
index 00000000000..a7295d9c532
--- /dev/null
+++ b/compiler/rustc_lint/src/utils.rs
@@ -0,0 +1,55 @@
+use rustc_hir::{Expr, ExprKind};
+use rustc_span::sym;
+
+use crate::LateContext;
+
+/// Given an expression, peel all of casts (`<expr> as ...`, `<expr>.cast{,_mut,_const}()`,
+/// `ptr::from_ref(<expr>)`, ...) and init expressions.
+///
+/// Returns the innermost expression and a boolean representing if one of the casts was
+/// `UnsafeCell::raw_get(<expr>)`
+pub(crate) fn peel_casts<'tcx>(
+    cx: &LateContext<'tcx>,
+    mut e: &'tcx Expr<'tcx>,
+) -> (&'tcx Expr<'tcx>, bool) {
+    let mut gone_trough_unsafe_cell_raw_get = false;
+
+    loop {
+        e = e.peel_blocks();
+        // <expr> as ...
+        e = if let ExprKind::Cast(expr, _) = e.kind {
+            expr
+        // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const()
+        } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
+            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+            && matches!(
+                cx.tcx.get_diagnostic_name(def_id),
+                Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const)
+            )
+        {
+            expr
+        // ptr::from_ref(<expr>), UnsafeCell::raw_get(<expr>) or mem::transmute<_, _>(<expr>)
+        } else if let ExprKind::Call(path, [arg]) = e.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && matches!(
+                cx.tcx.get_diagnostic_name(def_id),
+                Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute)
+            )
+        {
+            if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
+                gone_trough_unsafe_cell_raw_get = true;
+            }
+            arg
+        } else {
+            let init = cx.expr_or_init(e);
+            if init.hir_id != e.hir_id {
+                init
+            } else {
+                break;
+            }
+        };
+    }
+
+    (e, gone_trough_unsafe_cell_raw_get)
+}
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 7fa23dad698..39e45163707 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -638,7 +638,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::precedence::PRECEDENCE_INFO,
     crate::precedence::PRECEDENCE_BITS_INFO,
     crate::ptr::CMP_NULL_INFO,
-    crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
     crate::ptr::MUT_FROM_REF_INFO,
     crate::ptr::PTR_ARG_INFO,
     crate::ptr::PTR_EQ_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
index 0031da406f1..de66ead4f42 100644
--- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
@@ -131,6 +131,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
     ("clippy::clone_double_ref", "suspicious_double_ref_op"),
     #[clippy::version = ""]
     ("clippy::cmp_nan", "invalid_nan_comparisons"),
+    #[clippy::version = "CURRENT_RUSTC_VERSION"]
+    ("clippy::invalid_null_ptr_usage", "invalid_null_arguments"),
     #[clippy::version = "1.86.0"]
     ("clippy::double_neg", "double_negations"),
     #[clippy::version = ""]
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 55f1ece0559..50ef56db167 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -127,29 +127,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// This lint checks for invalid usages of `ptr::null`.
-    ///
-    /// ### Why is this bad?
-    /// This causes undefined behavior.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// // Undefined behavior
-    /// unsafe { std::slice::from_raw_parts(ptr::null(), 0); }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```ignore
-    /// unsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); }
-    /// ```
-    #[clippy::version = "1.53.0"]
-    pub INVALID_NULL_PTR_USAGE,
-    correctness,
-    "invalid usage of a null pointer, suggesting `NonNull::dangling()` instead"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Use `std::ptr::eq` when applicable
     ///
     /// ### Why is this bad?
@@ -177,7 +154,7 @@ declare_clippy_lint! {
     "use `std::ptr::eq` when comparing raw pointers"
 }
 
-declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USAGE, PTR_EQ]);
+declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, PTR_EQ]);
 
 impl<'tcx> LateLintPass<'tcx> for Ptr {
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
@@ -301,54 +278,6 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
                 format!("{non_null_path_snippet}.is_null()"),
                 Applicability::MachineApplicable,
             );
-        } else {
-            check_invalid_ptr_usage(cx, expr);
-        }
-    }
-}
-
-fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-    if let ExprKind::Call(fun, args) = expr.kind
-        && let ExprKind::Path(ref qpath) = fun.kind
-        && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
-        && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)
-    {
-        // TODO: `ptr_slice_from_raw_parts` and its mutable variant should probably still be linted
-        // conditionally based on how the return value is used, but not universally like the other
-        // functions since there are valid uses for null slice pointers.
-        //
-        // See: https://github.com/rust-lang/rust-clippy/pull/13452/files#r1773772034
-
-        // `arg` positions where null would cause U.B.
-        let arg_indices: &[_] = match name {
-            sym::ptr_read
-            | sym::ptr_read_unaligned
-            | sym::ptr_read_volatile
-            | sym::ptr_replace
-            | sym::ptr_write
-            | sym::ptr_write_bytes
-            | sym::ptr_write_unaligned
-            | sym::ptr_write_volatile
-            | sym::slice_from_raw_parts
-            | sym::slice_from_raw_parts_mut => &[0],
-            sym::ptr_copy | sym::ptr_copy_nonoverlapping | sym::ptr_swap | sym::ptr_swap_nonoverlapping => &[0, 1],
-            _ => return,
-        };
-
-        for &arg_idx in arg_indices {
-            if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg))
-                && let Some(std_or_core) = std_or_core(cx)
-            {
-                span_lint_and_sugg(
-                    cx,
-                    INVALID_NULL_PTR_USAGE,
-                    arg.span,
-                    "pointer must be non-null",
-                    "change this to",
-                    format!("{std_or_core}::ptr::NonNull::dangling().as_ptr()"),
-                    Applicability::MachineApplicable,
-                );
-            }
         }
     }
 }
diff --git a/src/tools/clippy/tests/ui/crashes/ice-1782.rs b/src/tools/clippy/tests/ui/crashes/ice-1782.rs
index fefdc405cce..4a1886c08af 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-1782.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-1782.rs
@@ -1,6 +1,6 @@
 //@ check-pass
 
-#![allow(dead_code, unused_variables)]
+#![allow(dead_code, unused_variables, invalid_null_arguments)]
 #![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)]
 
 /// Should not trigger an ICE in `SpanlessEq` / `consts::constant`
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
deleted file mode 100644
index ce78e89ee82..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
+++ /dev/null
@@ -1,66 +0,0 @@
-fn main() {
-    unsafe {
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(std::mem::size_of::<A>(), 0);
-
-        let _a: A = std::ptr::read(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_unaligned(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_unaligned(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_volatile(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_volatile(std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::replace(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
-
-        std::ptr::swap::<A>(std::ptr::NonNull::dangling().as_ptr(), &mut A);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap::<A>(&mut A, std::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::swap_nonoverlapping::<A>(std::ptr::NonNull::dangling().as_ptr(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_unaligned(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_volatile(std::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_bytes::<usize>(std::ptr::NonNull::dangling().as_ptr(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
deleted file mode 100644
index 361865fbd96..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-fn main() {
-    unsafe {
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(std::mem::size_of::<A>(), 0);
-
-        let _a: A = std::ptr::read(std::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read(std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_unaligned(std::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_unaligned(std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::read_volatile(std::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
-
-        std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_unaligned(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_volatile(std::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
deleted file mode 100644
index 3f9d15b9040..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
+++ /dev/null
@@ -1,136 +0,0 @@
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:3:59
-   |
-LL |         let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0);
-   |                                                           ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-   |
-   = note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:5:59
-   |
-LL |         let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0);
-   |                                                           ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:8:63
-   |
-LL |         let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0);
-   |                                                               ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:11:33
-   |
-LL |         std::ptr::copy::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                 ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:13:73
-   |
-LL |         std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-   |                                                                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:16:48
-   |
-LL |         std::ptr::copy_nonoverlapping::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                                ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:18:88
-   |
-LL |         std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
-   |                                                                                        ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:24:36
-   |
-LL |         let _a: A = std::ptr::read(std::ptr::null());
-   |                                    ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:26:36
-   |
-LL |         let _a: A = std::ptr::read(std::ptr::null_mut());
-   |                                    ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:29:46
-   |
-LL |         let _a: A = std::ptr::read_unaligned(std::ptr::null());
-   |                                              ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:31:46
-   |
-LL |         let _a: A = std::ptr::read_unaligned(std::ptr::null_mut());
-   |                                              ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:34:45
-   |
-LL |         let _a: A = std::ptr::read_volatile(std::ptr::null());
-   |                                             ^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:36:45
-   |
-LL |         let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
-   |                                             ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:39:39
-   |
-LL |         let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
-   |                                       ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:44:29
-   |
-LL |         std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
-   |                             ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:46:37
-   |
-LL |         std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
-   |                                     ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:49:44
-   |
-LL |         std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
-   |                                            ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:51:52
-   |
-LL |         std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
-   |                                                    ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:54:25
-   |
-LL |         std::ptr::write(std::ptr::null_mut(), A);
-   |                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:57:35
-   |
-LL |         std::ptr::write_unaligned(std::ptr::null_mut(), A);
-   |                                   ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:60:34
-   |
-LL |         std::ptr::write_volatile(std::ptr::null_mut(), A);
-   |                                  ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:63:40
-   |
-LL |         std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
-   |                                        ^^^^^^^^^^^^^^^^^^^^ help: change this to: `std::ptr::NonNull::dangling().as_ptr()`
-
-error: aborting due to 22 previous errors
-
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed
deleted file mode 100644
index df7ab166187..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.fixed
+++ /dev/null
@@ -1,79 +0,0 @@
-#![no_std]
-#![feature(lang_items)]
-
-use core::panic::PanicInfo;
-
-#[lang = "eh_personality"]
-extern "C" fn eh_personality() {}
-
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
-    loop {}
-}
-
-fn main() {
-    unsafe {
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(core::mem::size_of::<A>(), 0);
-
-        let _a: A = core::ptr::read(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_unaligned(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_unaligned(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::replace(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts(core::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut(), 0);
-
-        core::ptr::swap::<A>(core::ptr::NonNull::dangling().as_ptr(), &mut A);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap::<A>(&mut A, core::ptr::NonNull::dangling().as_ptr());
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::swap_nonoverlapping::<A>(core::ptr::NonNull::dangling().as_ptr(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap_nonoverlapping::<A>(&mut A, core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_unaligned(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_volatile(core::ptr::NonNull::dangling().as_ptr(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_bytes::<usize>(core::ptr::NonNull::dangling().as_ptr(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs
deleted file mode 100644
index 38ddfff0553..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-#![no_std]
-#![feature(lang_items)]
-
-use core::panic::PanicInfo;
-
-#[lang = "eh_personality"]
-extern "C" fn eh_personality() {}
-
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
-    loop {}
-}
-
-fn main() {
-    unsafe {
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null(), 0);
-        //~^ invalid_null_ptr_usage
-        let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        struct A; // zero sized struct
-        assert_eq!(core::mem::size_of::<A>(), 0);
-
-        let _a: A = core::ptr::read(core::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read(core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_unaligned(core::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_unaligned(core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::read_volatile(core::ptr::null());
-        //~^ invalid_null_ptr_usage
-        let _a: A = core::ptr::read_volatile(core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        let _a: A = core::ptr::replace(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts(core::ptr::null_mut(), 0); // shouldn't lint
-        let _slice: *const [usize] = core::ptr::slice_from_raw_parts_mut(core::ptr::null_mut(), 0);
-
-        core::ptr::swap::<A>(core::ptr::null_mut(), &mut A);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap::<A>(&mut A, core::ptr::null_mut());
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::swap_nonoverlapping::<A>(core::ptr::null_mut(), &mut A, 0);
-        //~^ invalid_null_ptr_usage
-        core::ptr::swap_nonoverlapping::<A>(&mut A, core::ptr::null_mut(), 0);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_unaligned(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_volatile(core::ptr::null_mut(), A);
-        //~^ invalid_null_ptr_usage
-
-        core::ptr::write_bytes::<usize>(core::ptr::null_mut(), 42, 0);
-        //~^ invalid_null_ptr_usage
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr
deleted file mode 100644
index b5dd21ce624..00000000000
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage_no_std.stderr
+++ /dev/null
@@ -1,136 +0,0 @@
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:16:60
-   |
-LL |         let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null(), 0);
-   |                                                            ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-   |
-   = note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:18:60
-   |
-LL |         let _slice: &[usize] = core::slice::from_raw_parts(core::ptr::null_mut(), 0);
-   |                                                            ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:21:64
-   |
-LL |         let _slice: &[usize] = core::slice::from_raw_parts_mut(core::ptr::null_mut(), 0);
-   |                                                                ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:24:34
-   |
-LL |         core::ptr::copy::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                  ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:26:75
-   |
-LL |         core::ptr::copy::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-   |                                                                           ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:29:49
-   |
-LL |         core::ptr::copy_nonoverlapping::<usize>(core::ptr::null(), core::ptr::NonNull::dangling().as_ptr(), 0);
-   |                                                 ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:31:90
-   |
-LL |         core::ptr::copy_nonoverlapping::<usize>(core::ptr::NonNull::dangling().as_ptr(), core::ptr::null_mut(), 0);
-   |                                                                                          ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:37:37
-   |
-LL |         let _a: A = core::ptr::read(core::ptr::null());
-   |                                     ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:39:37
-   |
-LL |         let _a: A = core::ptr::read(core::ptr::null_mut());
-   |                                     ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:42:47
-   |
-LL |         let _a: A = core::ptr::read_unaligned(core::ptr::null());
-   |                                               ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:44:47
-   |
-LL |         let _a: A = core::ptr::read_unaligned(core::ptr::null_mut());
-   |                                               ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:47:46
-   |
-LL |         let _a: A = core::ptr::read_volatile(core::ptr::null());
-   |                                              ^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:49:46
-   |
-LL |         let _a: A = core::ptr::read_volatile(core::ptr::null_mut());
-   |                                              ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:52:40
-   |
-LL |         let _a: A = core::ptr::replace(core::ptr::null_mut(), A);
-   |                                        ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:57:30
-   |
-LL |         core::ptr::swap::<A>(core::ptr::null_mut(), &mut A);
-   |                              ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:59:38
-   |
-LL |         core::ptr::swap::<A>(&mut A, core::ptr::null_mut());
-   |                                      ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:62:45
-   |
-LL |         core::ptr::swap_nonoverlapping::<A>(core::ptr::null_mut(), &mut A, 0);
-   |                                             ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:64:53
-   |
-LL |         core::ptr::swap_nonoverlapping::<A>(&mut A, core::ptr::null_mut(), 0);
-   |                                                     ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:67:26
-   |
-LL |         core::ptr::write(core::ptr::null_mut(), A);
-   |                          ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:70:36
-   |
-LL |         core::ptr::write_unaligned(core::ptr::null_mut(), A);
-   |                                    ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:73:35
-   |
-LL |         core::ptr::write_volatile(core::ptr::null_mut(), A);
-   |                                   ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage_no_std.rs:76:41
-   |
-LL |         core::ptr::write_bytes::<usize>(core::ptr::null_mut(), 42, 0);
-   |                                         ^^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: aborting due to 22 previous errors
-
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 501811fa491..79640470696 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -119,6 +119,7 @@
 #![warn(invalid_atomic_ordering)] //~ ERROR: lint `clippy::invalid_atomic_ordering`
 #![warn(invalid_value)] //~ ERROR: lint `clippy::invalid_ref`
 #![warn(invalid_from_utf8_unchecked)] //~ ERROR: lint `clippy::invalid_utf8_in_unchecked`
+#![warn(invalid_null_arguments)] //~ ERROR: lint `clippy::invalid_null_ptr_usage`
 #![warn(let_underscore_drop)] //~ ERROR: lint `clippy::let_underscore_drop`
 #![warn(unexpected_cfgs)] //~ ERROR: lint `clippy::maybe_misused_cfg`
 #![warn(enum_intrinsics_non_enums)] //~ ERROR: lint `clippy::mem_discriminant_non_enum`
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 7f4b8062e1b..aa7b905b4b8 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -119,6 +119,7 @@
 #![warn(clippy::invalid_atomic_ordering)] //~ ERROR: lint `clippy::invalid_atomic_ordering`
 #![warn(clippy::invalid_ref)] //~ ERROR: lint `clippy::invalid_ref`
 #![warn(clippy::invalid_utf8_in_unchecked)] //~ ERROR: lint `clippy::invalid_utf8_in_unchecked`
+#![warn(clippy::invalid_null_ptr_usage)] //~ ERROR: lint `clippy::invalid_null_ptr_usage`
 #![warn(clippy::let_underscore_drop)] //~ ERROR: lint `clippy::let_underscore_drop`
 #![warn(clippy::maybe_misused_cfg)] //~ ERROR: lint `clippy::maybe_misused_cfg`
 #![warn(clippy::mem_discriminant_non_enum)] //~ ERROR: lint `clippy::mem_discriminant_non_enum`
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index f24eaec3917..b3c88167c11 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -343,71 +343,77 @@ error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_fro
 LL | #![warn(clippy::invalid_utf8_in_unchecked)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
 
-error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
+error: lint `clippy::invalid_null_ptr_usage` has been renamed to `invalid_null_arguments`
   --> tests/ui/rename.rs:122:9
    |
+LL | #![warn(clippy::invalid_null_ptr_usage)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_null_arguments`
+
+error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
+  --> tests/ui/rename.rs:123:9
+   |
 LL | #![warn(clippy::let_underscore_drop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
 
 error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs`
-  --> tests/ui/rename.rs:123:9
+  --> tests/ui/rename.rs:124:9
    |
 LL | #![warn(clippy::maybe_misused_cfg)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
 
 error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> tests/ui/rename.rs:124:9
+  --> tests/ui/rename.rs:125:9
    |
 LL | #![warn(clippy::mem_discriminant_non_enum)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
 error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs`
-  --> tests/ui/rename.rs:125:9
+  --> tests/ui/rename.rs:126:9
    |
 LL | #![warn(clippy::mismatched_target_os)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
 
 error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> tests/ui/rename.rs:126:9
+  --> tests/ui/rename.rs:127:9
    |
 LL | #![warn(clippy::panic_params)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
 error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
-  --> tests/ui/rename.rs:127:9
+  --> tests/ui/rename.rs:128:9
    |
 LL | #![warn(clippy::positional_named_format_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
 
 error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
-  --> tests/ui/rename.rs:128:9
+  --> tests/ui/rename.rs:129:9
    |
 LL | #![warn(clippy::temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
 
 error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
-  --> tests/ui/rename.rs:129:9
+  --> tests/ui/rename.rs:130:9
    |
 LL | #![warn(clippy::undropped_manually_drops)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> tests/ui/rename.rs:130:9
+  --> tests/ui/rename.rs:131:9
    |
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
 error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> tests/ui/rename.rs:131:9
+  --> tests/ui/rename.rs:132:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
 error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`
-  --> tests/ui/rename.rs:132:9
+  --> tests/ui/rename.rs:133:9
    |
 LL | #![warn(clippy::vtable_address_comparisons)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`
 
-error: aborting due to 68 previous errors
+error: aborting due to 69 previous errors
 
diff --git a/tests/ui/lint/invalid_null_args.rs b/tests/ui/lint/invalid_null_args.rs
new file mode 100644
index 00000000000..7948f0d86d0
--- /dev/null
+++ b/tests/ui/lint/invalid_null_args.rs
@@ -0,0 +1,136 @@
+// check-fail
+// run-rustfix
+
+use std::ptr;
+use std::mem;
+
+unsafe fn null_ptr() {
+    ptr::write(
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+        ptr::null_mut() as *mut u32,
+        mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+    );
+
+    let null_ptr = ptr::null_mut();
+    ptr::write(
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+        null_ptr as *mut u32,
+        mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+    );
+
+    let _: &[usize] = std::slice::from_raw_parts(ptr::null(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _: &[usize] = std::slice::from_raw_parts(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _: &[usize] = std::slice::from_raw_parts(0 as *mut _, 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _: &[usize] = std::slice::from_raw_parts(mem::transmute(0usize), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _: &[usize] = std::slice::from_raw_parts_mut(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::copy::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::copy::<usize>(ptr::NonNull::dangling().as_ptr(), ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::copy_nonoverlapping::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::copy_nonoverlapping::<usize>(
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+        ptr::NonNull::dangling().as_ptr(),
+        ptr::null_mut(),
+        0
+    );
+
+    #[derive(Copy, Clone)]
+    struct A(usize);
+    let mut v = A(200);
+
+    let _a: A = ptr::read(ptr::null());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _a: A = ptr::read(ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _a: A = ptr::read_unaligned(ptr::null());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _a: A = ptr::read_unaligned(ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _a: A = ptr::read_volatile(ptr::null());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    let _a: A = ptr::read_volatile(ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    let _a: A = ptr::replace(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::swap::<A>(ptr::null_mut(), &mut v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::swap::<A>(&mut v, ptr::null_mut());
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write_unaligned(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write_volatile(ptr::null_mut(), v);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    // with indirections
+    let const_ptr = null_ptr as *const u8;
+    let _a: u8 = ptr::read(const_ptr);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+}
+
+unsafe fn zst() {
+    struct Zst; // zero-sized type
+
+    std::slice::from_raw_parts::<()>(ptr::null(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    std::slice::from_raw_parts::<Zst>(ptr::null(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+    std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0);
+    //~^ ERROR calling this function with a null pointer is undefined behavior
+
+    ptr::read::<()>(ptr::null());
+    ptr::read::<Zst>(ptr::null());
+
+    ptr::write(ptr::null_mut(), ());
+    ptr::write(ptr::null_mut(), Zst);
+
+    ptr::copy(ptr::null::<()>(), ptr::null_mut::<()>(), 1);
+    ptr::copy(ptr::null::<Zst>(), ptr::null_mut::<Zst>(), 1);
+}
+
+unsafe fn not_invalid() {
+    // Simplified false-positive from std quicksort implementation
+
+    let mut a = ptr::null_mut();
+    let mut b = ();
+
+    loop {
+        if false {
+            break;
+        }
+
+        a = &raw mut b;
+    }
+
+    ptr::write(a, ());
+}
+
+fn main() {}
diff --git a/tests/ui/lint/invalid_null_args.stderr b/tests/ui/lint/invalid_null_args.stderr
new file mode 100644
index 00000000000..f95bc2afa82
--- /dev/null
+++ b/tests/ui/lint/invalid_null_args.stderr
@@ -0,0 +1,330 @@
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:8:5
+   |
+LL | /     ptr::write(
+LL | |
+LL | |         ptr::null_mut() as *mut u32,
+   | |         --------------- null pointer originates from here
+LL | |         mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+LL | |     );
+   | |_____^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+   = note: `#[deny(invalid_null_arguments)]` on by default
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:15:5
+   |
+LL | /     ptr::write(
+LL | |
+LL | |         null_ptr as *mut u32,
+LL | |         mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),
+LL | |     );
+   | |_____^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+note: null pointer originates from here
+  --> $DIR/invalid_null_args.rs:14:20
+   |
+LL |     let null_ptr = ptr::null_mut();
+   |                    ^^^^^^^^^^^^^^^
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:21:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(ptr::null(), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                                  |
+   |                                                  null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:23:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(ptr::null_mut(), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                                  |
+   |                                                  null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:25:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(0 as *mut _, 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^
+   |                                                  |
+   |                                                  null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:27:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts(mem::transmute(0usize), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^
+   |                                                                 |
+   |                                                                 null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:30:23
+   |
+LL |     let _: &[usize] = std::slice::from_raw_parts_mut(ptr::null_mut(), 0);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                                      |
+   |                                                      null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:33:5
+   |
+LL |     ptr::copy::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                        |
+   |                        null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:35:5
+   |
+LL |     ptr::copy::<usize>(ptr::NonNull::dangling().as_ptr(), ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                                           |
+   |                                                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:38:5
+   |
+LL |     ptr::copy_nonoverlapping::<usize>(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                       |
+   |                                       null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:40:5
+   |
+LL | /     ptr::copy_nonoverlapping::<usize>(
+LL | |
+LL | |         ptr::NonNull::dangling().as_ptr(),
+LL | |         ptr::null_mut(),
+   | |         --------------- null pointer originates from here
+LL | |         0
+LL | |     );
+   | |_____^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:51:17
+   |
+LL |     let _a: A = ptr::read(ptr::null());
+   |                 ^^^^^^^^^^-----------^
+   |                           |
+   |                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:53:17
+   |
+LL |     let _a: A = ptr::read(ptr::null_mut());
+   |                 ^^^^^^^^^^---------------^
+   |                           |
+   |                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:56:17
+   |
+LL |     let _a: A = ptr::read_unaligned(ptr::null());
+   |                 ^^^^^^^^^^^^^^^^^^^^-----------^
+   |                                     |
+   |                                     null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:58:17
+   |
+LL |     let _a: A = ptr::read_unaligned(ptr::null_mut());
+   |                 ^^^^^^^^^^^^^^^^^^^^---------------^
+   |                                     |
+   |                                     null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:61:17
+   |
+LL |     let _a: A = ptr::read_volatile(ptr::null());
+   |                 ^^^^^^^^^^^^^^^^^^^-----------^
+   |                                    |
+   |                                    null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:63:17
+   |
+LL |     let _a: A = ptr::read_volatile(ptr::null_mut());
+   |                 ^^^^^^^^^^^^^^^^^^^---------------^
+   |                                    |
+   |                                    null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:66:17
+   |
+LL |     let _a: A = ptr::replace(ptr::null_mut(), v);
+   |                 ^^^^^^^^^^^^^---------------^^^^
+   |                              |
+   |                              null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:69:5
+   |
+LL |     ptr::swap::<A>(ptr::null_mut(), &mut v);
+   |     ^^^^^^^^^^^^^^^---------------^^^^^^^^^
+   |                    |
+   |                    null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:71:5
+   |
+LL |     ptr::swap::<A>(&mut v, ptr::null_mut());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:74:5
+   |
+LL |     ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^^^^^
+   |                                   |
+   |                                   null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:76:5
+   |
+LL |     ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                           |
+   |                                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:79:5
+   |
+LL |     ptr::write(ptr::null_mut(), v);
+   |     ^^^^^^^^^^^---------------^^^^
+   |                |
+   |                null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:82:5
+   |
+LL |     ptr::write_unaligned(ptr::null_mut(), v);
+   |     ^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                          |
+   |                          null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:85:5
+   |
+LL |     ptr::write_volatile(ptr::null_mut(), v);
+   |     ^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                         |
+   |                         null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:88:5
+   |
+LL |     ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^
+   |                               |
+   |                               null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:93:18
+   |
+LL |     let _a: u8 = ptr::read(const_ptr);
+   |                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+note: null pointer originates from here
+  --> $DIR/invalid_null_args.rs:14:20
+   |
+LL |     let null_ptr = ptr::null_mut();
+   |                    ^^^^^^^^^^^^^^^
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:100:5
+   |
+LL |     std::slice::from_raw_parts::<()>(ptr::null(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                      |
+   |                                      null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:102:5
+   |
+LL |     std::slice::from_raw_parts::<Zst>(ptr::null(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                       |
+   |                                       null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:104:5
+   |
+LL |     std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                          |
+   |                                          null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
+  --> $DIR/invalid_null_args.rs:106:5
+   |
+LL |     std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                                           |
+   |                                           null pointer originates from here
+   |
+   = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
+
+error: aborting due to 31 previous errors
+
diff --git a/tests/ui/precondition-checks/copy-nonoverlapping.rs b/tests/ui/precondition-checks/copy-nonoverlapping.rs
index 81018e4bff3..eacaa63e543 100644
--- a/tests/ui/precondition-checks/copy-nonoverlapping.rs
+++ b/tests/ui/precondition-checks/copy-nonoverlapping.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::copy_nonoverlapping requires
 //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/copy.rs b/tests/ui/precondition-checks/copy.rs
index 694853f950a..1fadd90bf70 100644
--- a/tests/ui/precondition-checks/copy.rs
+++ b/tests/ui/precondition-checks/copy.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::copy requires
 //@ revisions: null_src null_dst misaligned_src misaligned_dst
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs
index e14881d0290..ada8932c398 100644
--- a/tests/ui/precondition-checks/read_volatile.rs
+++ b/tests/ui/precondition-checks/read_volatile.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires
 //@ revisions: null misaligned
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/replace.rs b/tests/ui/precondition-checks/replace.rs
index 2808cee7b64..44afbd8174c 100644
--- a/tests/ui/precondition-checks/replace.rs
+++ b/tests/ui/precondition-checks/replace.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::replace requires
 //@ revisions: null misaligned
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
index 3801639e255..9b9ded69a83 100644
--- a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
+++ b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts_mut requires
 //@ revisions: null misaligned toolarge
 
+#![allow(invalid_null_arguments)]
+
 fn main() {
     unsafe {
         #[cfg(null)]
diff --git a/tests/ui/precondition-checks/slice-from-raw-parts.rs b/tests/ui/precondition-checks/slice-from-raw-parts.rs
index a3690fa045e..96578c1eae5 100644
--- a/tests/ui/precondition-checks/slice-from-raw-parts.rs
+++ b/tests/ui/precondition-checks/slice-from-raw-parts.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts requires
 //@ revisions: null misaligned toolarge
 
+#![allow(invalid_null_arguments)]
+
 fn main() {
     unsafe {
         #[cfg(null)]
diff --git a/tests/ui/precondition-checks/swap-nonoverlapping.rs b/tests/ui/precondition-checks/swap-nonoverlapping.rs
index 52e4a3c870b..ea1f6f36ad7 100644
--- a/tests/ui/precondition-checks/swap-nonoverlapping.rs
+++ b/tests/ui/precondition-checks/swap-nonoverlapping.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires
 //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs
index ac0b89b5ecf..0d5ecb014b3 100644
--- a/tests/ui/precondition-checks/write_volatile.rs
+++ b/tests/ui/precondition-checks/write_volatile.rs
@@ -3,6 +3,8 @@
 //@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires
 //@ revisions: null misaligned
 
+#![allow(invalid_null_arguments)]
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui/precondition-checks/zero-size-null.rs b/tests/ui/precondition-checks/zero-size-null.rs
index 43a81175f94..55d768fc9e5 100644
--- a/tests/ui/precondition-checks/zero-size-null.rs
+++ b/tests/ui/precondition-checks/zero-size-null.rs
@@ -7,8 +7,10 @@ use std::ptr;
 
 fn main() {
     unsafe {
+        #[expect(invalid_null_arguments)] // false-positive, copy of 0
         ptr::copy_nonoverlapping::<u8>(ptr::null(), ptr::null_mut(), 0);
         ptr::copy_nonoverlapping::<()>(ptr::null(), ptr::null_mut(), 123);
+        #[expect(invalid_null_arguments)] // false-positive, copy of 0
         ptr::copy::<u8>(ptr::null(), ptr::null_mut(), 0);
         ptr::copy::<()>(ptr::null(), ptr::null_mut(), 123);
         ptr::swap::<()>(ptr::null_mut(), ptr::null_mut());