@@ -6,7 +6,7 @@ use crate::ty::query::TyCtxtAt;
6
6
use crate :: ty:: { self , layout, tls, FnSig , Ty } ;
7
7
8
8
use rustc_data_structures:: sync:: Lock ;
9
- use rustc_errors:: { struct_span_err, DiagnosticBuilder , ErrorReported } ;
9
+ use rustc_errors:: { pluralize , struct_span_err, DiagnosticBuilder , ErrorReported } ;
10
10
use rustc_hir as hir;
11
11
use rustc_hir:: definitions:: DefPathData ;
12
12
use rustc_macros:: HashStable ;
@@ -327,6 +327,19 @@ impl fmt::Display for CheckInAllocMsg {
327
327
}
328
328
}
329
329
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
+
330
343
/// Error information for when the program caused Undefined Behavior.
331
344
pub enum UndefinedBehaviorInfo < ' tcx > {
332
345
/// Free-form case. Only for errors that are never caught!
@@ -384,7 +397,7 @@ pub enum UndefinedBehaviorInfo<'tcx> {
384
397
/// Using a string that is not valid UTF-8,
385
398
InvalidStr ( std:: str:: Utf8Error ) ,
386
399
/// Using uninitialized data where it is not allowed.
387
- InvalidUninitBytes ( Option < Pointer > ) ,
400
+ InvalidUninitBytes ( Option < Box < UninitBytesAccess > > ) ,
388
401
/// Working with a local that is not currently live.
389
402
DeadLocal ,
390
403
/// Data size is not equal to target size.
@@ -455,10 +468,18 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
455
468
write ! ( f, "using {} as function pointer but it does not point to a function" , p)
456
469
}
457
470
InvalidStr ( err) => write ! ( f, "this string is not valid UTF-8: {}" , err) ,
458
- InvalidUninitBytes ( Some ( p ) ) => write ! (
471
+ InvalidUninitBytes ( Some ( access ) ) => write ! (
459
472
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,
462
483
) ,
463
484
InvalidUninitBytes ( None ) => write ! (
464
485
f,
@@ -556,6 +577,9 @@ impl dyn MachineStopType {
556
577
}
557
578
}
558
579
580
+ #[ cfg( target_arch = "x86_64" ) ]
581
+ static_assert_size ! ( InterpError <' _>, 40 ) ;
582
+
559
583
pub enum InterpError < ' tcx > {
560
584
/// The program caused undefined behavior.
561
585
UndefinedBehavior ( UndefinedBehaviorInfo < ' tcx > ) ,
@@ -604,7 +628,10 @@ impl InterpError<'_> {
604
628
InterpError :: MachineStop ( b) => mem:: size_of_val :: < dyn MachineStopType > ( & * * b) > 0 ,
605
629
InterpError :: Unsupported ( UnsupportedOpInfo :: Unsupported ( _) )
606
630
| InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: ValidationFailure ( _) )
607
- | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: Ub ( _) ) => true ,
631
+ | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: Ub ( _) )
632
+ | InterpError :: UndefinedBehavior ( UndefinedBehaviorInfo :: InvalidUninitBytes ( Some ( _) ) ) => {
633
+ true
634
+ }
608
635
_ => false ,
609
636
}
610
637
}
0 commit comments