Skip to content

Commit e47eaef

Browse files
committed
Report the range of uninit bytes in CTFE errors
1 parent f46ce66 commit e47eaef

18 files changed

+40
-29
lines changed

compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use either::{Either, Left, Right};
77
use rustc_abi as abi;
88
use rustc_abi::{BackendRepr, HasDataLayout, Size};
99
use rustc_hir::def::Namespace;
10-
use rustc_middle::mir::interpret::ScalarSizeMismatch;
10+
use rustc_middle::mir::interpret::{BadBytesAccess, ScalarSizeMismatch};
1111
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
1212
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
1313
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
@@ -663,7 +663,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
663663
}
664664
let imm = self.read_immediate_raw(op)?.right().unwrap();
665665
if matches!(*imm, Immediate::Uninit) {
666-
throw_ub!(InvalidUninitBytes(None));
666+
throw_ub!(InvalidUninitBytes(match op.to_op(self)?.as_mplace_or_imm() {
667+
Left(mplace) => mplace.ptr().provenance.and_then(|prov| {
668+
let start = mplace.ptr().into_parts().1;
669+
let size = op.layout().size;
670+
let range = alloc_range(start, size);
671+
Some((prov.get_alloc_id()?, BadBytesAccess { access: range, bad: range }))
672+
}),
673+
Right(_) => None,
674+
}))
667675
}
668676
interp_ok(imm)
669677
}

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
397397
interp_ok(try_validation!(
398398
self.ecx.read_immediate(val),
399399
self.path,
400-
Ub(InvalidUninitBytes(None)) =>
400+
Ub(InvalidUninitBytes(_)) =>
401401
Uninit { expected },
402402
// The `Unsup` cases can only occur during CTFE
403403
Unsup(ReadPointerAsInt(_)) =>

compiler/rustc_middle/src/mir/interpret/allocation.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,11 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
700700
read_provenance: bool,
701701
) -> AllocResult<Scalar<Prov>> {
702702
// First and foremost, if anything is uninit, bail.
703-
if self.init_mask.is_range_initialized(range).is_err() {
704-
return Err(AllocError::InvalidUninitBytes(None));
703+
if let Err(bad) = self.init_mask.is_range_initialized(range) {
704+
return Err(AllocError::InvalidUninitBytes(Some(BadBytesAccess {
705+
access: range,
706+
bad,
707+
})));
705708
}
706709

707710
// Get the integer part of the result. We HAVE TO check provenance before returning this!

tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0080]: using uninitialized data, but this operation requires initialized memory
1+
error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory
22
--> $DIR/invalid-patterns.rs:40:32
33
|
44
LL | get_flag::<false, { unsafe { char_raw.character } }>();
@@ -26,7 +26,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
2626
42 │ B
2727
}
2828

29-
error[E0080]: using uninitialized data, but this operation requires initialized memory
29+
error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory
3030
--> $DIR/invalid-patterns.rs:44:58
3131
|
3232
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();

tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0080]: using uninitialized data, but this operation requires initialized memory
1+
error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory
22
--> $DIR/invalid-patterns.rs:40:32
33
|
44
LL | get_flag::<false, { unsafe { char_raw.character } }>();
@@ -26,7 +26,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
2626
42 │ B
2727
}
2828

29-
error[E0080]: using uninitialized data, but this operation requires initialized memory
29+
error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory
3030
--> $DIR/invalid-patterns.rs:44:58
3131
|
3232
LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();

tests/ui/consts/const-err-enum-discriminant.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0080]: using uninitialized data, but this operation requires initialized memory
1+
error[E0080]: reading memory at ALLOC0[0x0..0x8], but memory is uninitialized at [0x0..0x8], and this operation requires initialized memory
22
--> $DIR/const-err-enum-discriminant.rs:8:21
33
|
44
LL | Boo = [unsafe { Foo { b: () }.a }; 4][3],

tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
4343
= help: this code performed an operation that depends on the underlying bytes representing a pointer
4444
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
4545

46-
error[E0080]: using uninitialized data, but this operation requires initialized memory
46+
error[E0080]: reading memory at ALLOC0[0x0..0x10], but memory is uninitialized at [0x8..0x10], and this operation requires initialized memory
4747
--> $DIR/const-pointer-values-in-various-types.rs:42:47
4848
|
4949
LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
@@ -85,7 +85,7 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
8585
= help: this code performed an operation that depends on the underlying bytes representing a pointer
8686
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
8787

88-
error[E0080]: using uninitialized data, but this operation requires initialized memory
88+
error[E0080]: reading memory at ALLOC1[0x0..0x10], but memory is uninitialized at [0x8..0x10], and this operation requires initialized memory
8989
--> $DIR/const-pointer-values-in-various-types.rs:57:47
9090
|
9191
LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };

tests/ui/consts/const-eval/ub-enum-overwrite.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0080]: using uninitialized data, but this operation requires initialized memory
1+
error[E0080]: reading memory at ALLOC0[0x1..0x2], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory
22
--> $DIR/ub-enum-overwrite.rs:11:14
33
|
44
LL | unsafe { *p }

tests/ui/consts/const-eval/ub-enum.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
5656
= help: this code performed an operation that depends on the underlying bytes representing a pointer
5757
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
5858

59-
error[E0080]: using uninitialized data, but this operation requires initialized memory
59+
error[E0080]: reading memory at ALLOC0[0x0..0x8], but memory is uninitialized at [0x0..0x8], and this operation requires initialized memory
6060
--> $DIR/ub-enum.rs:61:41
6161
|
6262
LL | const BAD_ENUM2_UNDEF: Enum2 = unsafe { MaybeUninit { uninit: () }.init };

tests/ui/consts/const-eval/ub-nonnull.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
3737
HEX_DUMP
3838
}
3939

40-
error[E0080]: using uninitialized data, but this operation requires initialized memory
40+
error[E0080]: reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory
4141
--> $DIR/ub-nonnull.rs:36:38
4242
|
4343
LL | const UNINIT: NonZero<u8> = unsafe { MaybeUninit { uninit: () }.init };

0 commit comments

Comments
 (0)