@@ -21,7 +21,7 @@ use std::hash::Hash;
21
21
22
22
use super :: {
23
23
CheckInAllocMsg , GlobalAlloc , InterpCx , InterpResult , MPlaceTy , Machine , MemPlaceMeta , OpTy ,
24
- ValueVisitor ,
24
+ ScalarMaybeUninit , ValueVisitor ,
25
25
} ;
26
26
27
27
macro_rules! throw_validation_failure {
@@ -378,7 +378,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
378
378
value : OpTy < ' tcx , M :: PointerTag > ,
379
379
kind : & str ,
380
380
) -> 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
+ ) ;
382
386
// Handle wide pointers.
383
387
// Check metadata early, for better diagnostics
384
388
let place = try_validation ! (
@@ -485,6 +489,17 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
485
489
Ok ( ( ) )
486
490
}
487
491
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
+
488
503
/// Check if this is a value of primitive type, and if yes check the validity of the value
489
504
/// at that type. Return `true` if the type is indeed primitive.
490
505
fn try_visit_primitive (
@@ -495,7 +510,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
495
510
let ty = value. layout . ty ;
496
511
match ty. kind ( ) {
497
512
ty:: Bool => {
498
- let value = self . ecx . read_scalar ( value) ?;
513
+ let value = self . read_scalar ( value) ?;
499
514
try_validation ! (
500
515
value. to_bool( ) ,
501
516
self . path,
@@ -505,7 +520,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
505
520
Ok ( true )
506
521
}
507
522
ty:: Char => {
508
- let value = self . ecx . read_scalar ( value) ?;
523
+ let value = self . read_scalar ( value) ?;
509
524
try_validation ! (
510
525
value. to_char( ) ,
511
526
self . path,
@@ -515,11 +530,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
515
530
Ok ( true )
516
531
}
517
532
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) ?;
523
534
// NOTE: Keep this in sync with the array optimization for int/float
524
535
// types below!
525
536
if self . ctfe_mode . is_some ( ) {
@@ -541,9 +552,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
541
552
// actually enforce the strict rules for raw pointers (mostly because
542
553
// that lets us re-use `ref_to_mplace`).
543
554
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 ) ) ,
545
556
self . path,
546
557
err_ub!( InvalidUninitBytes ( None ) ) => { "uninitialized raw pointer" } ,
558
+ err_unsup!( ReadPointerAsBytes ) => { "part of a pointer" } expected { "a proper pointer or integer value" } ,
547
559
) ;
548
560
if place. layout . is_unsized ( ) {
549
561
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, '
569
581
Ok ( true )
570
582
}
571
583
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
+ ) ;
573
589
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) ) ,
575
591
self . path,
576
592
err_ub!( DanglingIntPointer ( ..) ) |
577
593
err_ub!( InvalidFunctionPointer ( ..) ) |
@@ -615,7 +631,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
615
631
op : OpTy < ' tcx , M :: PointerTag > ,
616
632
scalar_layout : & Scalar ,
617
633
) -> InterpResult < ' tcx > {
618
- let value = self . ecx . read_scalar ( op) ?;
634
+ let value = self . read_scalar ( op) ?;
619
635
let valid_range = & scalar_layout. valid_range ;
620
636
let ( lo, hi) = valid_range. clone ( ) . into_inner ( ) ;
621
637
// Determine the allowed range
0 commit comments