@@ -6,7 +6,7 @@ use crate::ty::query::TyCtxtAt;
66use crate :: ty:: { self , layout, tls, FnSig , Ty } ;
77
88use rustc_data_structures:: sync:: Lock ;
9- use rustc_errors:: { struct_span_err, DiagnosticBuilder , ErrorReported } ;
9+ use rustc_errors:: { pluralize , struct_span_err, DiagnosticBuilder , ErrorReported } ;
1010use rustc_hir as hir;
1111use rustc_hir:: definitions:: DefPathData ;
1212use rustc_macros:: HashStable ;
@@ -327,6 +327,19 @@ impl fmt::Display for CheckInAllocMsg {
327327 }
328328}
329329
330+ /// Details of an access to uninitialized bytes where it is not allowed.
331+ #[ derive( Debug ) ]
332+ pub struct UninitBytesAccess {
333+ /// Location of the original memory access.
334+ pub access_ptr : Pointer ,
335+ /// Size of the original memory access.
336+ pub access_size : Size ,
337+ /// Location of the first uninitialized byte that was accessed.
338+ pub uninit_ptr : Pointer ,
339+ /// Number of consecutive uninitialized bytes that were accessed.
340+ pub uninit_size : Size ,
341+ }
342+
330343/// Error information for when the program caused Undefined Behavior.
331344pub enum UndefinedBehaviorInfo < ' tcx > {
332345 /// Free-form case. Only for errors that are never caught!
@@ -384,7 +397,7 @@ pub enum UndefinedBehaviorInfo<'tcx> {
384397 /// Using a string that is not valid UTF-8,
385398 InvalidStr ( std:: str:: Utf8Error ) ,
386399 /// Using uninitialized data where it is not allowed.
387- InvalidUninitBytes ( Option < Pointer > ) ,
400+ InvalidUninitBytes ( Option < Box < UninitBytesAccess > > ) ,
388401 /// Working with a local that is not currently live.
389402 DeadLocal ,
390403 /// Data size is not equal to target size.
@@ -455,10 +468,18 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
455468 write ! ( f, "using {} as function pointer but it does not point to a function" , p)
456469 }
457470 InvalidStr ( err) => write ! ( f, "this string is not valid UTF-8: {}" , err) ,
458- InvalidUninitBytes ( Some ( p ) ) => write ! (
471+ InvalidUninitBytes ( Some ( access ) ) => write ! (
459472 f,
460- "reading uninitialized memory at {}, but this operation requires initialized memory" ,
461- p
473+ "reading {} byte{} of memory starting at {}, \
474+ but {} byte{} {} uninitialized starting at {}, \
475+ and this operation requires initialized memory",
476+ access. access_size. bytes( ) ,
477+ pluralize!( access. access_size. bytes( ) ) ,
478+ access. access_ptr,
479+ access. uninit_size. bytes( ) ,
480+ pluralize!( access. uninit_size. bytes( ) ) ,
481+ if access. uninit_size. bytes( ) != 1 { "are" } else { "is" } ,
482+ access. uninit_ptr,
462483 ) ,
463484 InvalidUninitBytes ( None ) => write ! (
464485 f,
@@ -556,6 +577,9 @@ impl dyn MachineStopType {
556577 }
557578}
558579
580+ #[ cfg( target_arch = "x86_64" ) ]
581+ static_assert_size ! ( InterpError <' _>, 40 ) ;
582+
559583pub enum InterpError < ' tcx > {
560584 /// The program caused undefined behavior.
561585 UndefinedBehavior ( UndefinedBehaviorInfo < ' tcx > ) ,
@@ -604,7 +628,10 @@ impl InterpError<'_> {
604628 InterpError :: MachineStop ( b) => mem:: size_of_val :: < dyn MachineStopType > ( & * * b) > 0 ,
605629 InterpError :: Unsupported ( UnsupportedOpInfo :: Unsupported ( _) )
606630 | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: ValidationFailure ( _) )
607- | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: Ub ( _) ) => true ,
631+ | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: Ub ( _) )
632+ | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: InvalidUninitBytes ( Some ( _) ) ) => {
633+ true
634+ }
608635 _ => false ,
609636 }
610637 }
0 commit comments