@@ -73,17 +73,18 @@ macro_rules! throw_validation_failure {
7373///
7474macro_rules! try_validation {
7575 ( $e: expr, $where: expr,
76- $( $p: pat ) |+ => { $( $what_fmt: expr ) ,+ } $( expected { $( $expected_fmt: expr ) ,+ } ) ? $ ( , ) ?
76+ $( $( $ p: pat ) |+ => { $( $what_fmt: expr ) ,+ } $( expected { $( $expected_fmt: expr ) ,+ } ) ? ) ,+ $ ( , ) ?
7777 ) => { {
7878 match $e {
7979 Ok ( x) => x,
8080 // We catch the error and turn it into a validation failure. We are okay with
8181 // allocation here as this can only slow down builds that fail anyway.
82- $( Err ( InterpErrorInfo { kind: $p, .. } ) ) |+ =>
82+ $( $ ( Err ( InterpErrorInfo { kind: $p, .. } ) ) |+ =>
8383 throw_validation_failure!(
8484 $where,
8585 { $( $what_fmt ) ,+ } $( expected { $( $expected_fmt ) ,+ } ) ?
8686 ) ,
87+ ) +
8788 #[ allow( unreachable_patterns) ]
8889 Err ( e) => Err :: <!, _>( e) ?,
8990 }
@@ -367,66 +368,45 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
367368 self . check_wide_ptr_meta ( place. meta , place. layout ) ?;
368369 }
369370 // 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+ ) ;
379376 let ( size, align) = size_and_align
380377 // for the purpose of validity, consider foreign types to have
381378 // alignment and size determined by the layout (size will be 0,
382379 // alignment should take attributes into account).
383380 . unwrap_or_else ( || ( place. layout . size , place. layout . align . abi ) ) ;
384381 // 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+ ) ;
430410 // Recursive checking
431411 if let Some ( ref mut ref_tracking) = self . ref_tracking_for_consts {
432412 if let Some ( ptr) = ptr {
@@ -710,23 +690,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
710690 assert ! ( op. layout. ty. builtin_deref( true ) . is_none( ) ) ;
711691
712692 // 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+ ) ;
730701
731702 // *After* all of this, check the ABI. We need to check the ABI to handle
732703 // 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>
825796 Ok ( ( ) ) => { }
826797 // Some error happened, try to provide a more detailed description.
827798 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.)
829801 match err. kind {
830802 err_ub ! ( InvalidUndefBytes ( Some ( ptr) ) ) => {
831803 // Some byte was uninitialized, determine which
0 commit comments