@@ -21,7 +21,7 @@ use std::hash::Hash;
2121
2222use super :: {
2323 CheckInAllocMsg , GlobalAlloc , InterpCx , InterpResult , MPlaceTy , Machine , MemPlaceMeta , OpTy ,
24- ValueVisitor ,
24+ ScalarMaybeUninit , ValueVisitor ,
2525} ;
2626
2727macro_rules! throw_validation_failure {
@@ -378,7 +378,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
378378 value : OpTy < ' tcx , M :: PointerTag > ,
379379 kind : & str ,
380380 ) -> InterpResult < ' tcx > {
381- let value = self . ecx . read_immediate ( value) ?;
381+ let value = try_validation ! (
382+ self . ecx. read_immediate( value) ,
383+ self . path,
384+ err_unsup!( ReadPointerAsBytes ) => { "part of a pointer" } expected { "a proper pointer or integer value" } ,
385+ ) ;
382386 // Handle wide pointers.
383387 // Check metadata early, for better diagnostics
384388 let place = try_validation ! (
@@ -485,6 +489,17 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
485489 Ok ( ( ) )
486490 }
487491
492+ fn read_scalar (
493+ & self ,
494+ op : OpTy < ' tcx , M :: PointerTag > ,
495+ ) -> InterpResult < ' tcx , ScalarMaybeUninit < M :: PointerTag > > {
496+ Ok ( try_validation ! (
497+ self . ecx. read_scalar( op) ,
498+ self . path,
499+ err_unsup!( ReadPointerAsBytes ) => { "(potentially part of) a pointer" } expected { "plain (non-pointer) bytes" } ,
500+ ) )
501+ }
502+
488503 /// Check if this is a value of primitive type, and if yes check the validity of the value
489504 /// at that type. Return `true` if the type is indeed primitive.
490505 fn try_visit_primitive (
@@ -495,7 +510,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
495510 let ty = value. layout . ty ;
496511 match ty. kind ( ) {
497512 ty:: Bool => {
498- let value = self . ecx . read_scalar ( value) ?;
513+ let value = self . read_scalar ( value) ?;
499514 try_validation ! (
500515 value. to_bool( ) ,
501516 self . path,
@@ -505,7 +520,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
505520 Ok ( true )
506521 }
507522 ty:: Char => {
508- let value = self . ecx . read_scalar ( value) ?;
523+ let value = self . read_scalar ( value) ?;
509524 try_validation ! (
510525 value. to_char( ) ,
511526 self . path,
@@ -515,11 +530,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
515530 Ok ( true )
516531 }
517532 ty:: Float ( _) | ty:: Int ( _) | ty:: Uint ( _) => {
518- let value = try_validation ! (
519- self . ecx. read_scalar( value) ,
520- self . path,
521- err_unsup!( ReadPointerAsBytes ) => { "read of part of a pointer" } ,
522- ) ;
533+ let value = self . read_scalar ( value) ?;
523534 // NOTE: Keep this in sync with the array optimization for int/float
524535 // types below!
525536 if self . ctfe_mode . is_some ( ) {
@@ -541,9 +552,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
541552 // actually enforce the strict rules for raw pointers (mostly because
542553 // that lets us re-use `ref_to_mplace`).
543554 let place = try_validation ! (
544- self . ecx. ref_to_mplace ( self . ecx. read_immediate ( value ) ? ) ,
555+ self . ecx. read_immediate ( value ) . and_then ( |i| self . ecx. ref_to_mplace ( i ) ) ,
545556 self . path,
546557 err_ub!( InvalidUninitBytes ( None ) ) => { "uninitialized raw pointer" } ,
558+ err_unsup!( ReadPointerAsBytes ) => { "part of a pointer" } expected { "a proper pointer or integer value" } ,
547559 ) ;
548560 if place. layout . is_unsized ( ) {
549561 self . check_wide_ptr_meta ( place. meta , place. layout ) ?;
@@ -569,9 +581,13 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
569581 Ok ( true )
570582 }
571583 ty:: FnPtr ( _sig) => {
572- let value = self . ecx . read_scalar ( value) ?;
584+ let value = try_validation ! (
585+ self . ecx. read_immediate( value) ,
586+ self . path,
587+ err_unsup!( ReadPointerAsBytes ) => { "part of a pointer" } expected { "a proper pointer or integer value" } ,
588+ ) ;
573589 let _fn = try_validation ! (
574- value. check_init ( ) . and_then( |ptr| self . ecx. memory. get_fn( ptr) ) ,
590+ value. to_scalar ( ) . and_then( |ptr| self . ecx. memory. get_fn( ptr) ) ,
575591 self . path,
576592 err_ub!( DanglingIntPointer ( ..) ) |
577593 err_ub!( InvalidFunctionPointer ( ..) ) |
@@ -615,7 +631,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
615631 op : OpTy < ' tcx , M :: PointerTag > ,
616632 scalar_layout : & Scalar ,
617633 ) -> InterpResult < ' tcx > {
618- let value = self . ecx . read_scalar ( op) ?;
634+ let value = self . read_scalar ( op) ?;
619635 let valid_range = & scalar_layout. valid_range ;
620636 let ( lo, hi) = valid_range. clone ( ) . into_inner ( ) ;
621637 // Determine the allowed range
0 commit comments