@@ -19,9 +19,7 @@ use rustc_middle::mir::interpret::{
19
19
use rustc_middle:: ty;
20
20
use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
21
21
use 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 } ;
25
23
26
24
use std:: hash:: Hash ;
27
25
@@ -554,7 +552,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
554
552
// FIXME: Check if the signature matches
555
553
} else {
556
554
// 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 ) {
558
556
throw_validation_failure ! ( self . path, NullFnPtr ) ;
559
557
}
560
558
}
@@ -595,46 +593,36 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
595
593
) -> InterpResult < ' tcx > {
596
594
let size = scalar_layout. size ( self . ecx ) ;
597
595
let valid_range = scalar_layout. valid_range ( self . ecx ) ;
598
- let WrappingRange { start, end } = valid_range;
599
596
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
+ }
603
611
Err ( _) => {
604
612
// So this is a pointer then, and casting to an int failed.
605
613
// 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 ( ( ) )
620
618
} 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.
623
620
throw_validation_failure ! (
624
621
self . path,
625
622
PtrOutOfRange { range: valid_range, max_value }
626
623
)
627
624
}
628
625
}
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
- )
638
626
}
639
627
}
640
628
}
0 commit comments