@@ -73,17 +73,18 @@ macro_rules! throw_validation_failure {
73
73
///
74
74
macro_rules! try_validation {
75
75
( $e: expr, $where: expr,
76
- $( $p: pat ) |+ => { $( $what_fmt: expr ) ,+ } $( expected { $( $expected_fmt: expr ) ,+ } ) ? $ ( , ) ?
76
+ $( $( $ p: pat ) |+ => { $( $what_fmt: expr ) ,+ } $( expected { $( $expected_fmt: expr ) ,+ } ) ? ) ,+ $ ( , ) ?
77
77
) => { {
78
78
match $e {
79
79
Ok ( x) => x,
80
80
// We catch the error and turn it into a validation failure. We are okay with
81
81
// allocation here as this can only slow down builds that fail anyway.
82
- $( Err ( InterpErrorInfo { kind: $p, .. } ) ) |+ =>
82
+ $( $ ( Err ( InterpErrorInfo { kind: $p, .. } ) ) |+ =>
83
83
throw_validation_failure!(
84
84
$where,
85
85
{ $( $what_fmt ) ,+ } $( expected { $( $expected_fmt ) ,+ } ) ?
86
86
) ,
87
+ ) +
87
88
#[ allow( unreachable_patterns) ]
88
89
Err ( e) => Err :: <!, _>( e) ?,
89
90
}
@@ -367,66 +368,45 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
367
368
self . check_wide_ptr_meta ( place. meta , place. layout ) ?;
368
369
}
369
370
// Make sure this is dereferenceable and all.
370
- let size_and_align = match self . ecx . size_and_align_of ( place. meta , place. layout ) {
371
- Ok ( res) => res,
372
- Err ( err) => match err. kind {
373
- err_ub ! ( InvalidMeta ( msg) ) => throw_validation_failure ! ( self . path,
374
- { "invalid {} metadata: {}" , kind, msg }
375
- ) ,
376
- _ => bug ! ( "unexpected error during ptr size_and_align_of: {}" , err) ,
377
- } ,
378
- } ;
371
+ let size_and_align = try_validation ! (
372
+ self . ecx. size_and_align_of( place. meta, place. layout) ,
373
+ self . path,
374
+ err_ub!( InvalidMeta ( msg) ) => { "invalid {} metadata: {}" , kind, msg } ,
375
+ ) ;
379
376
let ( size, align) = size_and_align
380
377
// for the purpose of validity, consider foreign types to have
381
378
// alignment and size determined by the layout (size will be 0,
382
379
// alignment should take attributes into account).
383
380
. unwrap_or_else ( || ( place. layout . size , place. layout . align . abi ) ) ;
384
381
// Direct call to `check_ptr_access_align` checks alignment even on CTFE machines.
385
- let ptr: Option < _ > = match self . ecx . memory . check_ptr_access_align (
386
- place. ptr ,
387
- size,
388
- Some ( align) ,
389
- CheckInAllocMsg :: InboundsTest ,
390
- ) {
391
- Ok ( ptr) => ptr,
392
- Err ( err) => {
393
- info ! (
394
- "{:?} did not pass access check for size {:?}, align {:?}" ,
395
- place. ptr, size, align
396
- ) ;
397
- match err. kind {
398
- err_ub ! ( DanglingIntPointer ( 0 , _) ) => {
399
- throw_validation_failure ! ( self . path,
400
- { "a NULL {}" , kind }
401
- )
402
- }
403
- err_ub ! ( DanglingIntPointer ( i, _) ) => throw_validation_failure ! ( self . path,
404
- { "a {} to unallocated address {}" , kind, i }
405
- ) ,
406
- err_ub ! ( AlignmentCheckFailed { required, has } ) => throw_validation_failure ! (
407
- self . path,
408
- {
409
- "an unaligned {} (required {} byte alignment but found {})" ,
410
- kind,
411
- required. bytes( ) ,
412
- has. bytes( )
413
- }
414
- ) ,
415
- err_unsup ! ( ReadBytesAsPointer ) => throw_validation_failure ! ( self . path,
416
- { "a dangling {} (created from integer)" , kind }
417
- ) ,
418
- err_ub ! ( PointerOutOfBounds { .. } ) => throw_validation_failure ! ( self . path,
419
- { "a dangling {} (going beyond the bounds of its allocation)" , kind }
420
- ) ,
421
- // This cannot happen during const-eval (because interning already detects
422
- // dangling pointers), but it can happen in Miri.
423
- err_ub ! ( PointerUseAfterFree ( _) ) => throw_validation_failure ! ( self . path,
424
- { "a dangling {} (use-after-free)" , kind }
425
- ) ,
426
- _ => bug ! ( "Unexpected error during ptr inbounds test: {}" , err) ,
427
- }
428
- }
429
- } ;
382
+ let ptr: Option < _ > = try_validation ! (
383
+ self . ecx. memory. check_ptr_access_align(
384
+ place. ptr,
385
+ size,
386
+ Some ( align) ,
387
+ CheckInAllocMsg :: InboundsTest ,
388
+ ) ,
389
+ self . path,
390
+ err_ub!( DanglingIntPointer ( 0 , _) ) =>
391
+ { "a NULL {}" , kind } ,
392
+ err_ub!( DanglingIntPointer ( i, _) ) =>
393
+ { "a {} to unallocated address {}" , kind, i } ,
394
+ err_ub!( AlignmentCheckFailed { required, has } ) =>
395
+ {
396
+ "an unaligned {} (required {} byte alignment but found {})" ,
397
+ kind,
398
+ required. bytes( ) ,
399
+ has. bytes( )
400
+ } ,
401
+ err_unsup!( ReadBytesAsPointer ) =>
402
+ { "a dangling {} (created from integer)" , kind } ,
403
+ err_ub!( PointerOutOfBounds { .. } ) =>
404
+ { "a dangling {} (going beyond the bounds of its allocation)" , kind } ,
405
+ // This cannot happen during const-eval (because interning already detects
406
+ // dangling pointers), but it can happen in Miri.
407
+ err_ub!( PointerUseAfterFree ( _) ) =>
408
+ { "a dangling {} (use-after-free)" , kind } ,
409
+ ) ;
430
410
// Recursive checking
431
411
if let Some ( ref mut ref_tracking) = self . ref_tracking_for_consts {
432
412
if let Some ( ptr) = ptr {
@@ -710,23 +690,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
710
690
assert ! ( op. layout. ty. builtin_deref( true ) . is_none( ) ) ;
711
691
712
692
// Recursively walk the type. Translate some possible errors to something nicer.
713
- match self . walk_value ( op) {
714
- Ok ( ( ) ) => { }
715
- Err ( err) => match err. kind {
716
- err_ub ! ( InvalidDiscriminant ( val) ) => {
717
- throw_validation_failure ! ( self . path,
718
- { "{}" , val } expected { "a valid enum discriminant" }
719
- )
720
- }
721
- err_unsup ! ( ReadPointerAsBytes ) => {
722
- throw_validation_failure ! ( self . path,
723
- { "a pointer" } expected { "plain (non-pointer) bytes" }
724
- )
725
- }
726
- // Propagate upwards (that will also check for unexpected errors).
727
- _ => return Err ( err) ,
728
- } ,
729
- }
693
+ try_validation ! (
694
+ self . walk_value( op) ,
695
+ self . path,
696
+ err_ub!( InvalidDiscriminant ( val) ) =>
697
+ { "{}" , val } expected { "a valid enum discriminant" } ,
698
+ err_unsup!( ReadPointerAsBytes ) =>
699
+ { "a pointer" } expected { "plain (non-pointer) bytes" } ,
700
+ ) ;
730
701
731
702
// *After* all of this, check the ABI. We need to check the ABI to handle
732
703
// types like `NonNull` where the `Scalar` info is more restrictive than what
@@ -825,7 +796,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
825
796
Ok ( ( ) ) => { }
826
797
// Some error happened, try to provide a more detailed description.
827
798
Err ( err) => {
828
- // For some errors we might be able to provide extra information
799
+ // For some errors we might be able to provide extra information.
800
+ // (This custom logic does not fit the `try_validation!` macro.)
829
801
match err. kind {
830
802
err_ub ! ( InvalidUndefBytes ( Some ( ptr) ) ) => {
831
803
// Some byte was uninitialized, determine which
0 commit comments