@@ -19,9 +19,7 @@ use rustc_middle::mir::interpret::{
1919use rustc_middle:: ty;
2020use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
2121use rustc_span:: symbol:: { sym, Symbol } ;
22- use rustc_target:: abi:: {
23- Abi , FieldIdx , Scalar as ScalarAbi , Size , VariantIdx , Variants , WrappingRange ,
24- } ;
22+ use rustc_target:: abi:: { Abi , FieldIdx , Scalar as ScalarAbi , Size , VariantIdx , Variants } ;
2523
2624use std:: hash:: Hash ;
2725
@@ -554,7 +552,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
554552 // FIXME: Check if the signature matches
555553 } else {
556554 // Otherwise (for standalone Miri), we have to still check it to be non-null.
557- if self . ecx . scalar_may_be_null ( value) ? {
555+ if self . ecx . ptr_scalar_range ( value) ?. contains ( & 0 ) {
558556 throw_validation_failure ! ( self . path, NullFnPtr ) ;
559557 }
560558 }
@@ -595,46 +593,36 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
595593 ) -> InterpResult < ' tcx > {
596594 let size = scalar_layout. size ( self . ecx ) ;
597595 let valid_range = scalar_layout. valid_range ( self . ecx ) ;
598- let WrappingRange { start, end } = valid_range;
599596 let max_value = size. unsigned_int_max ( ) ;
600- assert ! ( end <= max_value) ;
601- let bits = match scalar. try_to_int ( ) {
602- Ok ( int) => int. assert_bits ( size) ,
597+ assert ! ( valid_range. end <= max_value) ;
598+ match scalar. try_to_int ( ) {
599+ Ok ( int) => {
600+ // We have an explicit int: check it against the valid range.
601+ let bits = int. assert_bits ( size) ;
602+ if valid_range. contains ( bits) {
603+ Ok ( ( ) )
604+ } else {
605+ throw_validation_failure ! (
606+ self . path,
607+ OutOfRange { value: format!( "{bits}" ) , range: valid_range, max_value }
608+ )
609+ }
610+ }
603611 Err ( _) => {
604612 // So this is a pointer then, and casting to an int failed.
605613 // Can only happen during CTFE.
606- // We support 2 kinds of ranges here: full range, and excluding zero.
607- if start == 1 && end == max_value {
608- // Only null is the niche. So make sure the ptr is NOT null.
609- if self . ecx . scalar_may_be_null ( scalar) ? {
610- throw_validation_failure ! (
611- self . path,
612- NullablePtrOutOfRange { range: valid_range, max_value }
613- )
614- } else {
615- return Ok ( ( ) ) ;
616- }
617- } else if scalar_layout. is_always_valid ( self . ecx ) {
618- // Easy. (This is reachable if `enforce_number_validity` is set.)
619- return Ok ( ( ) ) ;
614+ // We check if the possible addresses are compatible with the valid range.
615+ let range = self . ecx . ptr_scalar_range ( scalar) ?;
616+ if valid_range. contains_range ( range) {
617+ Ok ( ( ) )
620618 } else {
621- // Conservatively, we reject, because the pointer *could* have a bad
622- // value.
619+ // Reject conservatively, because the pointer *could* have a bad value.
623620 throw_validation_failure ! (
624621 self . path,
625622 PtrOutOfRange { range: valid_range, max_value }
626623 )
627624 }
628625 }
629- } ;
630- // Now compare.
631- if valid_range. contains ( bits) {
632- Ok ( ( ) )
633- } else {
634- throw_validation_failure ! (
635- self . path,
636- OutOfRange { value: format!( "{bits}" ) , range: valid_range, max_value }
637- )
638626 }
639627 }
640628}
0 commit comments