From 81711747150a34d91b6642f973fe2379bf12907a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 7 Oct 2025 19:16:58 +0200 Subject: [PATCH] fix panic with extra-const-ub-checks --- compiler/rustc_const_eval/messages.ftl | 5 ++++- compiler/rustc_const_eval/src/errors.rs | 5 ++--- .../src/interpret/validity.rs | 8 +++----- .../rustc_middle/src/mir/interpret/error.rs | 5 ++++- .../consts/extra-const-ub/detect-extra-ub.rs | 10 ++++++++++ .../detect-extra-ub.with_flag.stderr | 20 +++++++++++++++---- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 13a49e80cf2dc..3a2b3f8843191 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -481,7 +481,10 @@ const_eval_validation_null_box = {$front_matter}: encountered a {$maybe -> [true] maybe-null *[false] null } box -const_eval_validation_null_fn_ptr = {$front_matter}: encountered a null function pointer +const_eval_validation_null_fn_ptr = {$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } function pointer const_eval_validation_null_ref = {$front_matter}: encountered a {$maybe -> [true] maybe-null *[false] null diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index d352a6384245f..a0958a2b9ef3a 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -666,7 +666,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { PartialPointer => const_eval_validation_partial_pointer, MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable, MutableRefInConst => const_eval_validation_mutable_ref_in_const, - NullFnPtr => const_eval_validation_null_fn_ptr, + NullFnPtr { .. } => const_eval_validation_null_fn_ptr, NeverVal => const_eval_validation_never_val, NonnullPtrMaybeNull { .. } => const_eval_validation_nonnull_ptr_out_of_range, PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range, @@ -820,12 +820,11 @@ 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 { maybe, .. } => { + NullPtr { maybe, .. } | NullFnPtr { maybe } => { err.arg("maybe", maybe); } MutableRefToImmutable | MutableRefInConst - | NullFnPtr | NonnullPtrMaybeNull | NeverVal | UnsafeCellInImmutable diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 5f088fe37e80b..c62a23eb0b34b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -757,14 +757,12 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { ); // FIXME: Check if the signature matches } else { - // Otherwise (for standalone Miri), we have to still check it to be non-null. + // Otherwise (for standalone Miri and for `-Zextra-const-ub-checks`), + // 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); + throw_validation_failure!(self.path, NullFnPtr { maybe }); } } if self.reset_provenance_and_padding { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 951aac503fee8..976c209977b06 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -497,7 +497,10 @@ pub enum ValidationErrorKind<'tcx> { MutableRefToImmutable, UnsafeCellInImmutable, MutableRefInConst, - NullFnPtr, + NullFnPtr { + /// Records whether this pointer is definitely null or just may be null. + maybe: bool, + }, NeverVal, NonnullPtrMaybeNull, PtrOutOfRange { diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs index e17bac603b415..60086acc3707e 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -52,6 +52,16 @@ const UNALIGNED_PTR: () = unsafe { //[with_flag]~^ ERROR: invalid value }; +// A function pointer offset to be maybe-null. +const MAYBE_NULL_FN_PTR: () = unsafe { + let _x: fn() = transmute({ + //[with_flag]~^ ERROR: invalid value + fn fun() {} + let ptr = fun as fn(); + (ptr as *const u8).wrapping_add(10) + }); +}; + const UNINHABITED_VARIANT: () = unsafe { let data = [1u8]; // Not using transmute, we want to hit the ImmTy code path. diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 6af72868045ac..96c1666a2d2eb 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -37,14 +37,26 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ evaluation of `UNALIGNED_PTR` failed here +error[E0080]: constructing invalid value: encountered a maybe-null function pointer + --> $DIR/detect-extra-ub.rs:57:20 + | +LL | let _x: fn() = transmute({ + | ____________________^ +LL | | +LL | | fn fun() {} +LL | | let ptr = fun as fn(); +LL | | (ptr as *const u8).wrapping_add(10) +LL | | }); + | |______^ evaluation of `MAYBE_NULL_FN_PTR` failed here + error[E0080]: constructing invalid value at .: encountered an uninhabited enum variant - --> $DIR/detect-extra-ub.rs:58:13 + --> $DIR/detect-extra-ub.rs:68:13 | LL | let v = *addr_of!(data).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINHABITED_VARIANT` failed here error[E0080]: constructing invalid value at [0]: encountered a partial pointer or a mix of pointers - --> $DIR/detect-extra-ub.rs:77:16 + --> $DIR/detect-extra-ub.rs:87:16 | LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `PARTIAL_POINTER` failed here @@ -53,11 +65,11 @@ LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object - --> $DIR/detect-extra-ub.rs:91:16 + --> $DIR/detect-extra-ub.rs:101:16 | LL | let _val = &*slice; | ^^^^^^^ evaluation of `OVERSIZED_REF` failed here -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0080`.