about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-09-24 12:12:41 +0200
committerRalf Jung <post@ralfj.de>2025-09-24 13:35:29 +0200
commit8328c3dada0c888b1c570f97314b3f697d4b2a96 (patch)
tree2e1ec7d3bf0c3b02a51d1255ea1ec1c3617c2d4f /compiler/rustc_const_eval/src
parent0a41add6293d76b165968d70f95e7edbbe65fe11 (diff)
downloadrust-8328c3dada0c888b1c570f97314b3f697d4b2a96.tar.gz
rust-8328c3dada0c888b1c570f97314b3f697d4b2a96.zip
const validation: better error for maybe-null references
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/errors.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs13
2 files changed, 16 insertions, 7 deletions
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 29bddd59ffd..d352a638424 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -696,8 +696,8 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
             }
             UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box,
 
-            NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box,
-            NullPtr { ptr_kind: PointerKind::Ref(_) } => const_eval_validation_null_ref,
+            NullPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_null_box,
+            NullPtr { ptr_kind: PointerKind::Ref(_), .. } => const_eval_validation_null_ref,
             DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
                 const_eval_validation_dangling_box_no_provenance
             }
@@ -820,8 +820,10 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
                 err.arg("vtable_dyn_type", vtable_dyn_type.to_string());
                 err.arg("expected_dyn_type", expected_dyn_type.to_string());
             }
-            NullPtr { .. }
-            | MutableRefToImmutable
+            NullPtr { maybe, .. } => {
+                err.arg("maybe", maybe);
+            }
+            MutableRefToImmutable
             | MutableRefInConst
             | NullFnPtr
             | NonnullPtrMaybeNull
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 8648b83b8dc..5f088fe37e8 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -511,7 +511,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                 CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
             ),
             self.path,
-            Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind },
+            Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind, maybe: false },
             Ub(DanglingIntPointer { addr: i, .. }) => DanglingPtrNoProvenance {
                 ptr_kind,
                 // FIXME this says "null pointer" when null but we need translate
@@ -538,8 +538,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
         );
         // Make sure this is non-null. We checked dereferenceability above, but if `size` is zero
         // that does not imply non-null.
-        if self.ecx.scalar_may_be_null(Scalar::from_maybe_pointer(place.ptr(), self.ecx))? {
-            throw_validation_failure!(self.path, NullPtr { ptr_kind })
+        let scalar = Scalar::from_maybe_pointer(place.ptr(), self.ecx);
+        if self.ecx.scalar_may_be_null(scalar)? {
+            let maybe = !M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..));
+            throw_validation_failure!(self.path, NullPtr { ptr_kind, maybe })
         }
         // Do not allow references to uninhabited types.
         if place.layout.is_uninhabited() {
@@ -757,6 +759,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                 } else {
                     // Otherwise (for standalone Miri), we have to still check it to be non-null.
                     if self.ecx.scalar_may_be_null(scalar)? {
+                        let maybe =
+                            !M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..));
+                        // This can't be a "maybe-null" pointer since the check for this being
+                        // a fn ptr at all already ensures that the pointer is inbounds.
+                        assert!(!maybe);
                         throw_validation_failure!(self.path, NullFnPtr);
                     }
                 }