diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 4321bdf9aae..c792a27ab4c 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let min_align = match this.tcx.sess.target.arch.as_ref() { "x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8, "x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" => 16, - arch => bug!("Unsupported target architecture: {}", arch), + arch => bug!("unsupported target architecture for malloc: `{}`", arch), }; // Windows always aligns, even small allocations. // Source: @@ -320,7 +320,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(Some(body)); } - this.handle_unsupported(format!("can't call foreign function: {link_name}"))?; + this.handle_unsupported(format!( + "can't call foreign function `{link_name}` on OS `{os}`", + os = this.tcx.sess.target.os, + ))?; return Ok(None); } } @@ -336,9 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> { let this = self.eval_context_mut(); - let allocator_kind = if let Some(allocator_kind) = this.tcx.allocator_kind(()) { - allocator_kind - } else { + let Some(allocator_kind) = this.tcx.allocator_kind(()) else { // in real code, this symbol does not exist without an allocator return Ok(EmulateByNameResult::NotSupported); }; @@ -420,9 +421,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr).map_err(|_e| { - err_machine_stop!(TerminationInfo::Abort( - format!("pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}") - )) + err_machine_stop!(TerminationInfo::Abort(format!( + "pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}" + ))) })?; this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; } @@ -438,7 +439,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr = this.read_pointer(ptr)?; let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr)?; if offset != Size::ZERO { - throw_unsup_format!("pointer passed to miri_static_root must point to beginning of an allocated block"); + throw_unsup_format!( + "pointer passed to miri_static_root must point to beginning of an allocated block" + ); } this.machine.static_roots.push(alloc_id); } @@ -453,7 +456,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We read this as a plain OsStr and write it as a path, which will convert it to the target. let path = this.read_os_str_from_c_str(ptr)?.to_owned(); - let (success, needed_size) = this.write_path_to_c_str(Path::new(&path), out, out_size)?; + let (success, needed_size) = + this.write_path_to_c_str(Path::new(&path), out, out_size)?; // Return value: 0 on success, otherwise the size it would have needed. this.write_int(if success { 0 } else { needed_size }, dest)?; } @@ -505,11 +509,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_pointer(res, dest)?; } "calloc" => { - let [items, len] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [items, len] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let items = this.read_machine_usize(items)?; let len = this.read_machine_usize(len)?; - let size = - items.checked_mul(len).ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?; + let size = items + .checked_mul(len) + .ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?; let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C)?; this.write_pointer(res, dest)?; } @@ -519,7 +525,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.free(ptr, MiriMemoryKind::C)?; } "realloc" => { - let [old_ptr, new_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [old_ptr, new_size] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_machine_usize(new_size)?; let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?; @@ -551,11 +558,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; match link_name.as_str() { - "__rust_alloc" => return this.emulate_allocator(Symbol::intern("__rg_alloc"), default), + "__rust_alloc" => + return this.emulate_allocator(Symbol::intern("__rg_alloc"), default), "miri_alloc" => { default(this)?; return Ok(EmulateByNameResult::NeedsJumping); - }, + } _ => unreachable!(), } } @@ -574,7 +582,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { )?; // We just allocated this, the access is definitely in-bounds. - this.write_bytes_ptr(ptr.into(), iter::repeat(0u8).take(usize::try_from(size).unwrap())).unwrap(); + this.write_bytes_ptr( + ptr.into(), + iter::repeat(0u8).take(usize::try_from(size).unwrap()), + ) + .unwrap(); this.write_pointer(ptr, dest) }); } @@ -600,7 +612,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }; match link_name.as_str() { - "__rust_dealloc" => return this.emulate_allocator(Symbol::intern("__rg_dealloc"), default), + "__rust_dealloc" => + return this.emulate_allocator(Symbol::intern("__rg_dealloc"), default), "miri_dealloc" => { default(this)?; return Ok(EmulateByNameResult::NeedsJumping); @@ -609,7 +622,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } "__rust_realloc" => { - let [ptr, old_size, align, new_size] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr, old_size, align, new_size] = + this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_machine_usize(old_size)?; let align = this.read_machine_usize(align)?; @@ -633,7 +647,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // C memory handling functions "memcmp" => { - let [left, right, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [left, right, n] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; let n = Size::from_bytes(this.read_machine_usize(n)?); @@ -653,7 +668,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(Scalar::from_i32(result), dest)?; } "memrchr" => { - let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [ptr, val, num] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_machine_usize(num)?; @@ -676,7 +692,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } "memchr" => { - let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [ptr, val, num] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_machine_usize(num)?; @@ -699,7 +716,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let n = this.read_c_str(ptr)?.len(); - this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?; + this.write_scalar( + Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), + dest, + )?; } // math functions (note that there are also intrinsics for some other functions) @@ -835,7 +855,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let a = this.read_scalar(a)?.to_u64()?; let b = this.read_scalar(b)?.to_u64()?; - #[allow(clippy::integer_arithmetic)] // adding two u64 and a u8 cannot wrap in a u128 + #[allow(clippy::integer_arithmetic)] + // adding two u64 and a u8 cannot wrap in a u128 let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b); #[allow(clippy::integer_arithmetic)] // it's a u128, we can shift by 64 let (c_out, sum) = ((wide_sum >> 64).truncate::(), wide_sum.truncate::()); @@ -845,7 +866,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let sum_field = this.place_field(dest, 1)?; this.write_scalar(Scalar::from_u64(sum), &sum_field)?; } - "llvm.x86.sse2.pause" if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" => { + "llvm.x86.sse2.pause" + if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" => + { let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.yield_active_thread(); } @@ -853,7 +876,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; match arg { - 15 => { // SY ("full system scope") + // SY ("full system scope") + 15 => { this.yield_active_thread(); } _ => { @@ -863,11 +887,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Platform-specific shims - _ => match this.tcx.sess.target.os.as_ref() { - target if target_os_is_unix(target) => return shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), - "windows" => return shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), - target => throw_unsup_format!("the target `{}` is not supported", target), - } + _ => + return match this.tcx.sess.target.os.as_ref() { + target_os if target_os_is_unix(target_os) => + shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name( + this, link_name, abi, args, dest, + ), + "windows" => + shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name( + this, link_name, abi, args, dest, + ), + _ => Ok(EmulateByNameResult::NotSupported), + }, }; // We only fall through to here if we did *not* hit the `_` arm above, // i.e., if we actually emulated the function with one of the shims. diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 7768772338a..ca31efa486c 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -257,16 +257,11 @@ impl TlsDtorsState { // And move to the final state. self.0 = Done; } - "wasi" | "none" => { - // No OS, no TLS dtors. + _ => { + // No TLS dtor support. // FIXME: should we do something on wasi? self.0 = Done; } - os => { - throw_unsup_format!( - "the TLS machinery does not know how to handle OS `{os}`" - ); - } } } PthreadDtors(state) => { diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 7f43afb7820..d018a7ea252 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -596,13 +596,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Platform-specific shims _ => { let target_os = &*this.tcx.sess.target.os; - match target_os { - "android" => return shims::unix::android::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), - "freebsd" => return shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), - "linux" => return shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), - "macos" => return shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), - _ => panic!("unsupported Unix OS {target_os}"), - } + return match target_os { + "android" => shims::unix::android::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), + "freebsd" => shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), + "linux" => shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), + "macos" => shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest), + _ => Ok(EmulateByNameResult::NotSupported), + }; } }; diff --git a/src/tools/miri/tests/extern-so/fail/function_not_in_so.rs b/src/tools/miri/tests/extern-so/fail/function_not_in_so.rs index 3aaeb632cad..3540c75b73a 100644 --- a/src/tools/miri/tests/extern-so/fail/function_not_in_so.rs +++ b/src/tools/miri/tests/extern-so/fail/function_not_in_so.rs @@ -1,5 +1,6 @@ //@only-target-linux //@only-on-host +//@normalize-stderr-test: "OS `.*`" -> "$$OS" extern "C" { fn foo(); @@ -7,6 +8,6 @@ extern "C" { fn main() { unsafe { - foo(); //~ ERROR: unsupported operation: can't call foreign function: foo + foo(); //~ ERROR: unsupported operation: can't call foreign function `foo` } } diff --git a/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr b/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr index f649f0ae43e..e9bc3220471 100644 --- a/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr +++ b/src/tools/miri/tests/extern-so/fail/function_not_in_so.stderr @@ -1,8 +1,8 @@ -error: unsupported operation: can't call foreign function: foo +error: unsupported operation: can't call foreign function `foo` on $OS --> $DIR/function_not_in_so.rs:LL:CC | LL | foo(); - | ^^^^^ can't call foreign function: foo + | ^^^^^ can't call foreign function `foo` on $OS | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: BACKTRACE: diff --git a/src/tools/miri/tests/fail/alloc/no_global_allocator.rs b/src/tools/miri/tests/fail/alloc/no_global_allocator.rs index fb0e7986bb5..624ad1bda58 100644 --- a/src/tools/miri/tests/fail/alloc/no_global_allocator.rs +++ b/src/tools/miri/tests/fail/alloc/no_global_allocator.rs @@ -1,3 +1,4 @@ +//@normalize-stderr-test: "OS `.*`" -> "$$OS" // Make sure we pretend the allocation symbols don't exist when there is no allocator #![feature(lang_items, start)] @@ -10,7 +11,7 @@ extern "Rust" { #[start] fn start(_: isize, _: *const *const u8) -> isize { unsafe { - __rust_alloc(1, 1); //~ERROR: unsupported operation: can't call foreign function: __rust_alloc + __rust_alloc(1, 1); //~ERROR: unsupported operation: can't call foreign function `__rust_alloc` } 0 diff --git a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr index ea70970ae0f..fe6a22fadc9 100644 --- a/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr +++ b/src/tools/miri/tests/fail/alloc/no_global_allocator.stderr @@ -1,8 +1,8 @@ -error: unsupported operation: can't call foreign function: __rust_alloc +error: unsupported operation: can't call foreign function `__rust_alloc` on $OS --> $DIR/no_global_allocator.rs:LL:CC | LL | __rust_alloc(1, 1); - | ^^^^^^^^^^^^^^^^^^ can't call foreign function: __rust_alloc + | ^^^^^^^^^^^^^^^^^^ can't call foreign function `__rust_alloc` on $OS | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: BACKTRACE: diff --git a/src/tools/miri/tests/fail/unsupported_foreign_function.rs b/src/tools/miri/tests/fail/unsupported_foreign_function.rs index dfd099e734b..44f032fbabe 100644 --- a/src/tools/miri/tests/fail/unsupported_foreign_function.rs +++ b/src/tools/miri/tests/fail/unsupported_foreign_function.rs @@ -1,9 +1,11 @@ +//@normalize-stderr-test: "OS `.*`" -> "$$OS" + fn main() { extern "Rust" { fn foo(); } unsafe { - foo(); //~ ERROR: unsupported operation: can't call foreign function: foo + foo(); //~ ERROR: unsupported operation: can't call foreign function `foo` } } diff --git a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr index fde5fb78ac0..519f6d182d7 100644 --- a/src/tools/miri/tests/fail/unsupported_foreign_function.stderr +++ b/src/tools/miri/tests/fail/unsupported_foreign_function.stderr @@ -1,8 +1,8 @@ -error: unsupported operation: can't call foreign function: foo +error: unsupported operation: can't call foreign function `foo` on $OS --> $DIR/unsupported_foreign_function.rs:LL:CC | LL | foo(); - | ^^^^^ can't call foreign function: foo + | ^^^^^ can't call foreign function `foo` on $OS | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: BACKTRACE: diff --git a/src/tools/miri/tests/fail/unsupported_signal.rs b/src/tools/miri/tests/fail/unsupported_incomplete_function.rs similarity index 85% rename from src/tools/miri/tests/fail/unsupported_signal.rs rename to src/tools/miri/tests/fail/unsupported_incomplete_function.rs index d50041ffbd9..6ef842c9ccb 100644 --- a/src/tools/miri/tests/fail/unsupported_signal.rs +++ b/src/tools/miri/tests/fail/unsupported_incomplete_function.rs @@ -1,10 +1,11 @@ //! `signal()` is special on Linux and macOS that it's only supported within libstd. //! The implementation is not complete enough to permit user code to call it. //@ignore-target-windows: No libc on Windows +//@normalize-stderr-test: "OS `.*`" -> "$$OS" fn main() { unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN); - //~^ ERROR: unsupported operation: can't call foreign function: signal + //~^ ERROR: unsupported operation: can't call foreign function `signal` } } diff --git a/src/tools/miri/tests/fail/unsupported_signal.stderr b/src/tools/miri/tests/fail/unsupported_incomplete_function.stderr similarity index 64% rename from src/tools/miri/tests/fail/unsupported_signal.stderr rename to src/tools/miri/tests/fail/unsupported_incomplete_function.stderr index d22ecbc11ff..ec2bba61172 100644 --- a/src/tools/miri/tests/fail/unsupported_signal.stderr +++ b/src/tools/miri/tests/fail/unsupported_incomplete_function.stderr @@ -1,12 +1,12 @@ -error: unsupported operation: can't call foreign function: signal - --> $DIR/unsupported_signal.rs:LL:CC +error: unsupported operation: can't call foreign function `signal` on $OS + --> $DIR/unsupported_incomplete_function.rs:LL:CC | LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function: signal + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `signal` on $OS | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: BACKTRACE: - = note: inside `main` at $DIR/unsupported_signal.rs:LL:CC + = note: inside `main` at $DIR/unsupported_incomplete_function.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/panic/unsupported_foreign_function.rs b/src/tools/miri/tests/panic/unsupported_foreign_function.rs index a78646528fb..b8301c50772 100644 --- a/src/tools/miri/tests/panic/unsupported_foreign_function.rs +++ b/src/tools/miri/tests/panic/unsupported_foreign_function.rs @@ -1,4 +1,5 @@ //@compile-flags: -Zmiri-panic-on-unsupported +//@normalize-stderr-test: "OS `.*`" -> "$$OS" fn main() { extern "Rust" { diff --git a/src/tools/miri/tests/panic/unsupported_foreign_function.stderr b/src/tools/miri/tests/panic/unsupported_foreign_function.stderr index 9af3e48655f..a49dbdae58a 100644 --- a/src/tools/miri/tests/panic/unsupported_foreign_function.stderr +++ b/src/tools/miri/tests/panic/unsupported_foreign_function.stderr @@ -1,2 +1,2 @@ -thread 'main' panicked at 'unsupported Miri functionality: can't call foreign function: foo', $DIR/unsupported_foreign_function.rs:LL:CC +thread 'main' panicked at 'unsupported Miri functionality: can't call foreign function `foo` on $OS', $DIR/unsupported_foreign_function.rs:LL:CC note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace