@@ -647,6 +647,25 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
647647 None
648648 }
649649 } else {
650+ // We are not checking dereferenceability, but we still want to ensure that the pointer
651+ // *could* be dereferenceable in *some* memory: we have to be able to compute the
652+ // address at the end of this range without overflowing..
653+ let scalar = Scalar :: from_maybe_pointer ( place. ptr ( ) , self . ecx ) ;
654+ // Skip this if we don't know the absolute address (during CTFE).
655+ if let Ok ( addr) = scalar. try_to_scalar_int ( ) {
656+ // Try to compute the end address.
657+ let addr = Size :: from_bytes ( addr. to_target_usize ( * self . ecx . tcx ) ) ;
658+ if addr. checked_add ( size, self . ecx ) . is_none ( ) {
659+ throw_validation_failure ! (
660+ self . path,
661+ format!(
662+ "encountered a {ptr_kind} that is too close to the end of the address space for a pointee of {} bytes" ,
663+ size. bytes( ) ,
664+ )
665+ )
666+ }
667+ }
668+
650669 // Pointer remains unchanged.
651670 None
652671 } ;
@@ -658,20 +677,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
658677 self . reset_pointer_provenance ( value, & ptr) ?;
659678 }
660679
661- // Check alignment after dereferenceable (if both are violated, trigger the error above).
662- try_validation ! (
663- self . ecx. check_ptr_align(
664- place. ptr( ) ,
665- align,
666- ) ,
667- self . path,
668- Ub ( AlignmentCheckFailed ( Misalignment { required, has } , _msg) ) => format!(
669- "encountered an unaligned {ptr_kind} (required {required_bytes} byte alignment but found {found_bytes})" ,
670- required_bytes = required. bytes( ) ,
671- found_bytes = has. bytes( )
672- ) ,
673- ) ;
674-
675680 // Make sure this is non-null. This is obviously needed when `may_dangle` is set,
676681 // but even if we did check dereferenceability above that would still allow null
677682 // pointers if `size` is zero.
@@ -686,6 +691,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
686691 )
687692 )
688693 }
694+
689695 // Do not allow references to uninhabited types.
690696 if !place. layout . ty . is_opsem_inhabited ( * self . ecx . tcx , self . ecx . typing_env ) {
691697 let ty = place. layout . ty ;
@@ -695,6 +701,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
695701 )
696702 }
697703
704+ // Check alignment after dereferenceable (if both are violated, trigger the error above).
705+ try_validation ! (
706+ self . ecx. check_ptr_align(
707+ place. ptr( ) ,
708+ align,
709+ ) ,
710+ self . path,
711+ Ub ( AlignmentCheckFailed ( Misalignment { required, has } , _msg) ) => format!(
712+ "encountered an unaligned {ptr_kind} (required {required_bytes} byte alignment but found {found_bytes})" ,
713+ required_bytes = required. bytes( ) ,
714+ found_bytes = has. bytes( )
715+ ) ,
716+ ) ;
717+
698718 // Recursive checking (but not inside `MaybeDangling` of course).
699719 if let Some ( ref_tracking) = self . ref_tracking . as_deref_mut ( )
700720 && !self . may_dangle
0 commit comments