Skip to content

Commit 3f9d3a4

Browse files
committed
Auto merge of #143350 - matthiaskrgr:rollup-zcuvkve, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang/rust#143192 (Improve CSS for source code block line numbers) - rust-lang/rust#143251 (bootstrap: add build.tidy-extra-checks option) - rust-lang/rust#143273 (Make the enum check work for negative discriminants) - rust-lang/rust#143292 (Explicitly handle all nodes in `generics_of` when computing parent) - rust-lang/rust#143316 (Add bootstrap check snapshot tests) - rust-lang/rust#143321 (byte-addresses memory -> byte-addressed memory) - rust-lang/rust#143324 (interpret: move the native call preparation logic into Miri) - rust-lang/rust#143325 (Use non-global interner in `test_string_interning` in bootstrap) - rust-lang/rust#143327 (miri: improve errors for type validity assertion failures) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3cbe719 + 880ec81 commit 3f9d3a4

File tree

12 files changed

+65
-80
lines changed

12 files changed

+65
-80
lines changed

src/alloc_addresses/mod.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -466,17 +466,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
466466
Some((alloc_id, Size::from_bytes(rel_offset)))
467467
}
468468

469-
/// Prepare all exposed memory for a native call.
470-
/// This overapproximates the modifications which external code might make to memory:
471-
/// We set all reachable allocations as initialized, mark all reachable provenances as exposed
472-
/// and overwrite them with `Provenance::WILDCARD`.
473-
fn prepare_exposed_for_native_call(&mut self) -> InterpResult<'tcx> {
474-
let this = self.eval_context_mut();
475-
// We need to make a deep copy of this list, but it's fine; it also serves as scratch space
476-
// for the search within `prepare_for_native_call`.
477-
let exposed: Vec<AllocId> =
478-
this.machine.alloc_addresses.get_mut().exposed.iter().copied().collect();
479-
this.prepare_for_native_call(exposed)
469+
/// Return a list of all exposed allocations.
470+
fn exposed_allocs(&self) -> Vec<AllocId> {
471+
let this = self.eval_context_ref();
472+
this.machine.alloc_addresses.borrow().exposed.iter().copied().collect()
480473
}
481474
}
482475

src/intrinsics/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
457457
throw_machine_stop!(TerminationInfo::Abort(format!("trace/breakpoint trap")))
458458
}
459459

460+
"assert_inhabited" | "assert_zero_valid" | "assert_mem_uninitialized_valid" => {
461+
// Make these a NOP, so we get the better Miri-native error messages.
462+
}
463+
460464
_ => return interp_ok(EmulateItemResult::NotSupported),
461465
}
462466

src/shims/native_lib/mod.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
198198
let mut libffi_args = Vec::<CArg>::with_capacity(args.len());
199199
for arg in args.iter() {
200200
if !matches!(arg.layout.backend_repr, BackendRepr::Scalar(_)) {
201-
throw_unsup_format!("only scalar argument types are support for native calls")
201+
throw_unsup_format!("only scalar argument types are supported for native calls")
202202
}
203203
let imm = this.read_immediate(arg)?;
204204
libffi_args.push(imm_to_carg(&imm, this)?);
@@ -224,16 +224,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
224224
this.expose_provenance(prov)?;
225225
}
226226
}
227-
228-
// Prepare all exposed memory.
229-
this.prepare_exposed_for_native_call()?;
230-
231-
// Convert them to `libffi::high::Arg` type.
227+
// Convert arguments to `libffi::high::Arg` type.
232228
let libffi_args = libffi_args
233229
.iter()
234230
.map(|arg| arg.arg_downcast())
235231
.collect::<Vec<libffi::high::Arg<'_>>>();
236232

233+
// Prepare all exposed memory (both previously exposed, and just newly exposed since a
234+
// pointer was passed as argument).
235+
this.visit_reachable_allocs(this.exposed_allocs(), |this, alloc_id, info| {
236+
// If there is no data behind this pointer, skip this.
237+
if !matches!(info.kind, AllocKind::LiveData) {
238+
return interp_ok(());
239+
}
240+
// It's okay to get raw access, what we do does not correspond to any actual
241+
// AM operation, it just approximates the state to account for the native call.
242+
let alloc = this.get_alloc_raw(alloc_id)?;
243+
// Also expose the provenance of the interpreter-level allocation, so it can
244+
// be read by FFI. The `black_box` is defensive programming as LLVM likes
245+
// to (incorrectly) optimize away ptr2int casts whose result is unused.
246+
std::hint::black_box(alloc.get_bytes_unchecked_raw().expose_provenance());
247+
// Expose all provenances in this allocation, since the native code can do $whatever.
248+
for prov in alloc.provenance().provenances() {
249+
this.expose_provenance(prov)?;
250+
}
251+
252+
// Prepare for possible write from native code if mutable.
253+
if info.mutbl.is_mut() {
254+
let alloc = &mut this.get_alloc_raw_mut(alloc_id)?.0;
255+
alloc.prepare_for_native_access();
256+
// Also expose *mutable* provenance for the interpreter-level allocation.
257+
std::hint::black_box(alloc.get_bytes_unchecked_raw_mut().expose_provenance());
258+
}
259+
260+
interp_ok(())
261+
})?;
262+
237263
// Call the function and store output, depending on return type in the function signature.
238264
let (ret, maybe_memevents) =
239265
this.call_native_with_args(link_name, dest, code_ptr, libffi_args)?;
@@ -321,7 +347,8 @@ fn imm_to_carg<'tcx>(v: &ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'
321347
CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()),
322348
ty::RawPtr(..) => {
323349
let s = v.to_scalar().to_pointer(cx)?.addr();
324-
// This relies on the `expose_provenance` in `prepare_for_native_call`.
350+
// This relies on the `expose_provenance` in the `visit_reachable_allocs` callback
351+
// above.
325352
CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize()))
326353
}
327354
_ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty),

tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() {
2020
let mut buf: MaybeUninit<[u8; 4]> = std::mem::MaybeUninit::uninit();
2121
// Read 4 bytes from a 3-byte file.
2222
assert_eq!(libc::read(fd, buf.as_mut_ptr().cast::<std::ffi::c_void>(), 4), 3);
23-
buf.assume_init(); //~ERROR: Undefined Behavior: constructing invalid value at .value[3]: encountered uninitialized memory, but expected an integer
23+
buf.assume_init(); //~ERROR: encountered uninitialized memory, but expected an integer
2424
assert_eq!(libc::close(fd), 0);
2525
}
2626
remove_file(&path).unwrap();

tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: Undefined Behavior: constructing invalid value at .value[3]: encountered uninitialized memory, but expected an integer
1+
error: Undefined Behavior: constructing invalid value at [3]: encountered uninitialized memory, but expected an integer
22
--> tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs:LL:CC
33
|
4-
LL | ... buf.assume_init();
5-
| ^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
4+
LL | buf.assume_init();
5+
| ^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
//@normalize-stderr-test: "\|.*::abort\(\).*" -> "| ABORT()"
2-
//@normalize-stderr-test: "\| +\^+" -> "| ^"
3-
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> ""
4-
//@normalize-stderr-test: "\n +at [^\n]+" -> ""
5-
//@error-in-other-file: aborted execution
61
#![feature(never_type)]
72

83
#[allow(deprecated, invalid_value)]
94
fn main() {
10-
let _ = unsafe { std::mem::uninitialized::<!>() };
5+
let _ = unsafe { std::mem::uninitialized::<!>() }; //~ERROR: constructing invalid value
116
}

tests/fail/intrinsics/uninit_uninhabited_type.stderr

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,13 @@
1-
2-
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
3-
aborted execution: attempted to instantiate uninhabited type `!`
4-
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
5-
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
6-
thread caused non-unwinding panic. aborting.
7-
error: abnormal termination: the program aborted execution
8-
--> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
9-
|
10-
LL | ABORT()
11-
| ^ abnormal termination occurred here
12-
|
13-
= note: BACKTRACE:
14-
= note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
15-
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
16-
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
17-
= note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
18-
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
19-
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
20-
note: inside `main`
1+
error: Undefined Behavior: constructing invalid value: encountered a value of the never type `!`
212
--> tests/fail/intrinsics/uninit_uninhabited_type.rs:LL:CC
223
|
234
LL | let _ = unsafe { std::mem::uninitialized::<!>() };
24-
| ^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at tests/fail/intrinsics/uninit_uninhabited_type.rs:LL:CC
2511

2612
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2713

tests/fail/intrinsics/zero_fn_ptr.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
//@normalize-stderr-test: "\|.*::abort\(\).*" -> "| ABORT()"
2-
//@normalize-stderr-test: "\| +\^+" -> "| ^"
3-
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> ""
4-
//@normalize-stderr-test: "\n +at [^\n]+" -> ""
5-
//@error-in-other-file: aborted execution
6-
71
#[allow(deprecated, invalid_value)]
82
fn main() {
9-
let _ = unsafe { std::mem::zeroed::<fn()>() };
3+
let _ = unsafe { std::mem::zeroed::<fn()>() }; //~ERROR: constructing invalid value
104
}

tests/fail/intrinsics/zero_fn_ptr.stderr

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,13 @@
1-
2-
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
3-
aborted execution: attempted to zero-initialize type `fn()`, which is invalid
4-
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
5-
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
6-
thread caused non-unwinding panic. aborting.
7-
error: abnormal termination: the program aborted execution
8-
--> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
9-
|
10-
LL | ABORT()
11-
| ^ abnormal termination occurred here
12-
|
13-
= note: BACKTRACE:
14-
= note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
15-
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
16-
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
17-
= note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
18-
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
19-
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
20-
note: inside `main`
1+
error: Undefined Behavior: constructing invalid value: encountered a null function pointer
212
--> tests/fail/intrinsics/zero_fn_ptr.rs:LL:CC
223
|
234
LL | let _ = unsafe { std::mem::zeroed::<fn()>() };
24-
| ^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at tests/fail/intrinsics/zero_fn_ptr.rs:LL:CC
2511

2612
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2713

tests/fail/validity/uninit_float.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Undefined Behavior: constructing invalid value at .value[0]: encountered uninitialized memory, but expected a floating point number
1+
error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a floating point number
22
--> tests/fail/validity/uninit_float.rs:LL:CC
33
|
44
LL | let _val: [f32; 1] = unsafe { std::mem::uninitialized() };

tests/fail/validity/uninit_integer.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Undefined Behavior: constructing invalid value at .value[0]: encountered uninitialized memory, but expected an integer
1+
error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected an integer
22
--> tests/fail/validity/uninit_integer.rs:LL:CC
33
|
44
LL | let _val = unsafe { std::mem::MaybeUninit::<[usize; 1]>::uninit().assume_init() };

tests/fail/validity/uninit_raw_ptr.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Undefined Behavior: constructing invalid value at .value[0]: encountered uninitialized memory, but expected a raw pointer
1+
error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a raw pointer
22
--> tests/fail/validity/uninit_raw_ptr.rs:LL:CC
33
|
44
LL | let _val = unsafe { std::mem::MaybeUninit::<[*const u8; 1]>::uninit().assume_init() };

0 commit comments

Comments
 (0)