Skip to content

Miri subtree update #141383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f9a75a0
Add more comment to libc-fs-with-isolation test
tiif May 18, 2025
3c50b9b
Merge pull request #4322 from tiif/move_test
RalfJung May 18, 2025
eb11adc
bump rustc-build-sysroot
RalfJung May 18, 2025
a4eb91f
Merge pull request #4330 from RalfJung/build-sysroot-bump
RalfJung May 18, 2025
b2a8690
Preparing for merge from rustc
May 19, 2025
1bb2d73
Merge from rustc
May 19, 2025
d5240cc
Merge pull request #4331 from rust-lang/rustup-2025-05-19
RalfJung May 19, 2025
0ba2a3a
enable clippy::as_conversions to fully rule out as-casts
RalfJung May 18, 2025
446fa22
add to_u64() helper method and use it where appropriate
RalfJung May 19, 2025
44d3c93
Merge pull request #4329 from RalfJung/no-casts
RalfJung May 19, 2025
aa4d16a
run tests on mips-unknown-linux-gnu
RalfJung May 19, 2025
8d46118
Merge pull request #4333 from RalfJung/mips-tests
RalfJung May 19, 2025
758b799
GetUserProfileDirectoryW: reference issue regarding implementation de…
RalfJung May 19, 2025
26e9172
Merge pull request #4334 from RalfJung/GetUserProfileDirectoryW-issue
RalfJung May 19, 2025
969a25b
Preparing for merge from rustc
RalfJung May 20, 2025
b13251e
Merge from rustc
RalfJung May 20, 2025
49482ca
Merge pull request #4335 from RalfJung/rustup
RalfJung May 20, 2025
293b0ac
Preparing for merge from rustc
May 21, 2025
b5688fb
Merge from rustc
May 21, 2025
2f34354
test direct usage of io::{stdout,stderr,stdin}
RalfJung May 21, 2025
e12f911
Merge pull request #4336 from rust-lang/rustup-2025-05-21
RalfJung May 21, 2025
fe51193
Merge pull request #4337 from RalfJung/io
RalfJung May 21, 2025
0523554
FileDescription: improve read/write docs
RalfJung May 21, 2025
febe988
Merge pull request #4338 from RalfJung/FileDescription
RalfJung May 21, 2025
5dfcb12
Implement FreeBSD syscall cpuset_getaffinity.
LorrensP-2158466 Apr 22, 2025
e065e27
Merge pull request #4287 from LorrensP-2158466/freebsd-num-cpus
RalfJung May 21, 2025
5955969
run the full test suite under FreeBSD
RalfJung May 21, 2025
4a18888
document that the entire test suite passes under freebsd
RalfJung May 21, 2025
268a369
Merge pull request #4341 from RalfJung/freebsd
RalfJung May 21, 2025
1e79637
Implement file read/write on Windows
CraftSpider Apr 10, 2025
9e1f3a5
enable isolated-stdin test on Windows
RalfJung May 22, 2025
2eb935d
Merge pull request #4275 from CraftSpider/windows-file-rw
RalfJung May 22, 2025
3f0c39d
update lockfile
RalfJung May 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3118,9 +3118,9 @@ dependencies = [

[[package]]
name = "rustc-build-sysroot"
version = "0.5.5"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb332121f7845c6bd016f9655cf22f03c2999df936694b624a88669a78667d98"
checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
dependencies = [
"anyhow",
"rustc_version",
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ degree documented below):
make no promises and we don't run tests for such targets.
- We have unofficial support (not maintained by the Miri team itself) for some further operating systems.
- `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite.
- `freebsd`: maintained by @YohDeadfall. Supports `std::env` and parts of `std::{thread, fs}`, but not `std::sync`.
- `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite.
- `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works.
- `wasi`: **maintainer wanted**. Support very incomplete, not even standard output works, but an empty `main` function works.
- For targets on other operating systems, Miri might fail before even reaching the `main` function.
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/cargo-miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,9 @@ dependencies = [

[[package]]
name = "rustc-build-sysroot"
version = "0.5.4"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6d984a9db43148467059309bd1e5ad577085162f695d9fe2cf3543aeb25cd38"
checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
dependencies = [
"anyhow",
"rustc_version",
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/cargo-miri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ directories = "6"
rustc_version = "0.4"
serde_json = "1.0.40"
cargo_metadata = "0.19"
rustc-build-sysroot = "0.5.4"
rustc-build-sysroot = "0.5.7"

# Enable some feature flags that dev-dependencies need but dependencies
# do not. This makes `./miri install` after `./miri build` faster.
Expand Down
13 changes: 7 additions & 6 deletions src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,17 @@ case $HOST_TARGET in
MANY_SEEDS=64 TEST_TARGET=i686-pc-windows-gnu run_tests
MANY_SEEDS=64 TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests
# Extra tier 2
TEST_TARGET=arm-unknown-linux-gnueabi run_tests
TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
MANY_SEEDS=16 TEST_TARGET=arm-unknown-linux-gnueabi run_tests
MANY_SEEDS=16 TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
# Not officially supported tier 2
TEST_TARGET=x86_64-unknown-illumos run_tests
TEST_TARGET=x86_64-pc-solaris run_tests
MANY_SEEDS=16 TEST_TARGET=mips-unknown-linux-gnu run_tests # a 32bit big-endian target, and also a target without 64bit atomics
MANY_SEEDS=16 TEST_TARGET=x86_64-unknown-illumos run_tests
MANY_SEEDS=16 TEST_TARGET=x86_64-pc-solaris run_tests
MANY_SEEDS=16 TEST_TARGET=x86_64-unknown-freebsd run_tests
MANY_SEEDS=16 TEST_TARGET=i686-unknown-freebsd run_tests
# Partially supported targets (tier 2)
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency fs libc-pipe
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency fs libc-pipe
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ac17c3486c6fdfbb0c3c18b99f3d8dfbff625d29
2b96ddca1272960623e41829439df8dae82d20af
2 changes: 1 addition & 1 deletion src/tools/miri/src/alloc_addresses/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
AllocKind::Dead => unreachable!(),
};
// We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
return interp_ok(base_ptr.addr().try_into().unwrap());
return interp_ok(base_ptr.addr().to_u64());
}
// We are not in native lib mode, so we control the addresses ourselves.
if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(
Expand Down
3 changes: 2 additions & 1 deletion src/tools/miri/src/alloc_addresses/reuse_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rand::Rng;
use rustc_abi::{Align, Size};

use crate::concurrency::VClock;
use crate::helpers::ToUsize as _;
use crate::{MemoryKind, MiriConfig, ThreadId};

const MAX_POOL_SIZE: usize = 64;
Expand Down Expand Up @@ -46,7 +47,7 @@ impl ReusePool {
}

fn subpool(&mut self, align: Align) -> &mut Vec<(u64, Size, ThreadId, VClock)> {
let pool_idx: usize = align.bytes().trailing_zeros().try_into().unwrap();
let pool_idx: usize = align.bytes().trailing_zeros().to_usize();
if self.pool.len() <= pool_idx {
self.pool.resize(pool_idx + 1, Vec::new());
}
Expand Down
6 changes: 4 additions & 2 deletions src/tools/miri/src/alloc_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{alloc, slice};
use rustc_abi::{Align, Size};
use rustc_middle::mir::interpret::AllocBytes;

use crate::helpers::ToU64 as _;

/// Allocation bytes that explicitly handle the layout of the data they're storing.
/// This is necessary to interface with native code that accesses the program store in Miri.
#[derive(Debug)]
Expand All @@ -21,7 +23,7 @@ pub struct MiriAllocBytes {
impl Clone for MiriAllocBytes {
fn clone(&self) -> Self {
let bytes: Cow<'_, [u8]> = Cow::Borrowed(self);
let align = Align::from_bytes(self.layout.align().try_into().unwrap()).unwrap();
let align = Align::from_bytes(self.layout.align().to_u64()).unwrap();
MiriAllocBytes::from_bytes(bytes, align)
}
}
Expand Down Expand Up @@ -90,7 +92,7 @@ impl AllocBytes for MiriAllocBytes {
let align = align.bytes();
// SAFETY: `alloc_fn` will only be used with `size != 0`.
let alloc_fn = |layout| unsafe { alloc::alloc(layout) };
let alloc_bytes = MiriAllocBytes::alloc_with(size.try_into().unwrap(), align, alloc_fn)
let alloc_bytes = MiriAllocBytes::alloc_with(size.to_u64(), align, alloc_fn)
.unwrap_or_else(|()| {
panic!("Miri ran out of memory: cannot create allocation of {size} bytes")
});
Expand Down
20 changes: 11 additions & 9 deletions src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use std::mem;

use rustc_data_structures::fx::FxHashMap;

use crate::helpers::ToUsize;

/// Intermediate key between a UniKeyMap and a UniValMap.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UniIndex {
Expand Down Expand Up @@ -158,7 +160,7 @@ where
impl<V> UniValMap<V> {
/// Whether this index has an associated value.
pub fn contains_idx(&self, idx: UniIndex) -> bool {
self.data.get(idx.idx as usize).and_then(Option::as_ref).is_some()
self.data.get(idx.idx.to_usize()).and_then(Option::as_ref).is_some()
}

/// Reserve enough space to insert the value at the right index.
Expand All @@ -174,29 +176,29 @@ impl<V> UniValMap<V> {

/// Assign a value to the index. Permanently overwrites any previous value.
pub fn insert(&mut self, idx: UniIndex, val: V) {
self.extend_to_length(idx.idx as usize + 1);
self.data[idx.idx as usize] = Some(val)
self.extend_to_length(idx.idx.to_usize() + 1);
self.data[idx.idx.to_usize()] = Some(val)
}

/// Get the value at this index, if it exists.
pub fn get(&self, idx: UniIndex) -> Option<&V> {
self.data.get(idx.idx as usize).and_then(Option::as_ref)
self.data.get(idx.idx.to_usize()).and_then(Option::as_ref)
}

/// Get the value at this index mutably, if it exists.
pub fn get_mut(&mut self, idx: UniIndex) -> Option<&mut V> {
self.data.get_mut(idx.idx as usize).and_then(Option::as_mut)
self.data.get_mut(idx.idx.to_usize()).and_then(Option::as_mut)
}

/// Delete any value associated with this index.
/// Returns None if the value was not present, otherwise
/// returns the previously stored value.
pub fn remove(&mut self, idx: UniIndex) -> Option<V> {
if idx.idx as usize >= self.data.len() {
if idx.idx.to_usize() >= self.data.len() {
return None;
}
let mut res = None;
mem::swap(&mut res, &mut self.data[idx.idx as usize]);
mem::swap(&mut res, &mut self.data[idx.idx.to_usize()]);
res
}
}
Expand All @@ -209,8 +211,8 @@ pub struct UniEntry<'a, V> {
impl<'a, V> UniValMap<V> {
/// Get a wrapper around a mutable access to the value corresponding to `idx`.
pub fn entry(&'a mut self, idx: UniIndex) -> UniEntry<'a, V> {
self.extend_to_length(idx.idx as usize + 1);
UniEntry { inner: &mut self.data[idx.idx as usize] }
self.extend_to_length(idx.idx.to_usize() + 1);
UniEntry { inner: &mut self.data[idx.idx.to_usize()] }
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/concurrency/cpu_affinity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl CpuAffinityMask {
let mut this = Self([0; Self::CPU_MASK_BYTES]);

// the default affinity mask includes only the available CPUs
for i in 0..cpu_count as usize {
for i in 0..cpu_count.to_usize() {
this.set(cx, i);
}

Expand Down
5 changes: 3 additions & 2 deletions src/tools/miri/src/concurrency/vector_clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_span::{DUMMY_SP, Span, SpanData};
use smallvec::SmallVec;

use super::data_race::NaReadType;
use crate::helpers::ToUsize;

/// A vector clock index, this is associated with a thread id
/// but in some cases one vector index may be shared with
Expand Down Expand Up @@ -157,7 +158,7 @@ impl VClock {

#[inline]
pub(super) fn index_mut(&mut self, index: VectorIdx) -> &mut VTimestamp {
self.0.as_mut_slice().get_mut(index.to_u32() as usize).unwrap()
self.0.as_mut_slice().get_mut(index.to_u32().to_usize()).unwrap()
}

/// Get a mutable slice to the internal vector with minimum `min_len`
Expand Down Expand Up @@ -420,7 +421,7 @@ impl Index<VectorIdx> for VClock {

#[inline]
fn index(&self, index: VectorIdx) -> &VTimestamp {
self.as_slice().get(index.to_u32() as usize).unwrap_or(&VTimestamp::ZERO)
self.as_slice().get(index.to_u32().to_usize()).unwrap_or(&VTimestamp::ZERO)
}
}

Expand Down
23 changes: 23 additions & 0 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1412,3 +1412,26 @@ pub(crate) fn windows_check_buffer_size((success, len): (bool, u64)) -> u32 {
u32::try_from(len).unwrap()
}
}

/// We don't support 16-bit systems, so let's have ergonomic conversion from `u32` to `usize`.
pub trait ToUsize {
fn to_usize(self) -> usize;
}

impl ToUsize for u32 {
fn to_usize(self) -> usize {
self.try_into().unwrap()
}
}

/// Similarly, a maximum address size of `u64` is assumed widely here, so let's have ergonomic
/// converion from `usize` to `u64`.
pub trait ToU64 {
fn to_u64(self) -> u64;
}

impl ToU64 for usize {
fn to_u64(self) -> u64 {
self.try_into().unwrap()
}
}
2 changes: 1 addition & 1 deletion src/tools/miri/src/intrinsics/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let index_len = index.len();

assert_eq!(left_len, right_len);
assert_eq!(index_len as u64, dest_len);
assert_eq!(u64::try_from(index_len).unwrap(), dest_len);

for i in 0..dest_len {
let src_index: u64 =
Expand Down
11 changes: 2 additions & 9 deletions src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,7 @@
rustc::potential_query_instability,
rustc::untranslatable_diagnostic,
)]
#![warn(
rust_2018_idioms,
unqualified_local_imports,
clippy::cast_possible_wrap, // unsigned -> signed
clippy::cast_sign_loss, // signed -> unsigned
clippy::cast_lossless,
clippy::cast_possible_truncation,
)]
#![warn(rust_2018_idioms, unqualified_local_imports, clippy::as_conversions)]
// Needed for rustdoc from bootstrap (with `-Znormalize-docs`).
#![recursion_limit = "256"]

Expand Down Expand Up @@ -140,7 +133,7 @@ pub use crate::eval::{
AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, MiriEntryFnType, RejectOpWith,
ValidationMode, create_ecx, eval_entry,
};
pub use crate::helpers::{AccessKind, EvalContextExt as _};
pub use crate::helpers::{AccessKind, EvalContextExt as _, ToU64 as _, ToUsize as _};
pub use crate::intrinsics::EvalContextExt as _;
pub use crate::machine::{
AllocExtra, DynMachineCallback, FrameExtra, MachineCallback, MemoryKind, MiriInterpCx,
Expand Down
5 changes: 0 additions & 5 deletions src/tools/miri/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,6 @@ pub struct MiriMachine<'tcx> {
/// Failure rate of compare_exchange_weak, between 0.0 and 1.0
pub(crate) cmpxchg_weak_failure_rate: f64,

/// Corresponds to -Zmiri-mute-stdout-stderr and doesn't write the output but acts as if it succeeded.
pub(crate) mute_stdout_stderr: bool,

/// The probability of the active thread being preempted at the end of each basic block.
pub(crate) preemption_rate: f64,

Expand Down Expand Up @@ -722,7 +719,6 @@ impl<'tcx> MiriMachine<'tcx> {
track_alloc_accesses: config.track_alloc_accesses,
check_alignment: config.check_alignment,
cmpxchg_weak_failure_rate: config.cmpxchg_weak_failure_rate,
mute_stdout_stderr: config.mute_stdout_stderr,
preemption_rate: config.preemption_rate,
report_progress: config.report_progress,
basic_block_count: 0,
Expand Down Expand Up @@ -925,7 +921,6 @@ impl VisitProvenance for MiriMachine<'_> {
track_alloc_accesses: _,
check_alignment: _,
cmpxchg_weak_failure_rate: _,
mute_stdout_stderr: _,
preemption_rate: _,
report_progress: _,
basic_block_count: _,
Expand Down
8 changes: 4 additions & 4 deletions src/tools/miri/src/shims/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

let frame_count = this.active_thread_stack().len();

this.write_scalar(Scalar::from_target_usize(frame_count.try_into().unwrap(), this), dest)
this.write_scalar(Scalar::from_target_usize(frame_count.to_u64(), this), dest)
}

fn handle_miri_get_backtrace(
Expand Down Expand Up @@ -70,7 +70,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
1 =>
for (i, ptr) in ptrs.into_iter().enumerate() {
let offset = ptr_layout.size.checked_mul(i.try_into().unwrap(), this).unwrap();
let offset = ptr_layout.size.checked_mul(i.to_u64(), this).unwrap();

let op_place = buf_place.offset(offset, ptr_layout, this)?;

Expand Down Expand Up @@ -158,11 +158,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
1 => {
this.write_scalar(
Scalar::from_target_usize(name.len().try_into().unwrap(), this),
Scalar::from_target_usize(name.len().to_u64(), this),
&this.project_field(dest, 0)?,
)?;
this.write_scalar(
Scalar::from_target_usize(filename.len().try_into().unwrap(), this),
Scalar::from_target_usize(filename.len().to_u64(), this),
&this.project_field(dest, 1)?,
)?;
}
Expand Down
10 changes: 8 additions & 2 deletions src/tools/miri/src/shims/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt {

/// Reads as much as possible into the given buffer `ptr`.
/// `len` indicates how many bytes we should try to read.
/// `dest` is where the return value should be stored: number of bytes read, or `-1` in case of error.
///
/// When the read is done, `finish` will be called. Note that `read` itself may return before
/// that happens! Everything that should happen "after" the `read` needs to happen inside
/// `finish`.
fn read<'tcx>(
self: FileDescriptionRef<Self>,
_communicate_allowed: bool,
Expand All @@ -149,7 +152,10 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt {

/// Writes as much as possible from the given buffer `ptr`.
/// `len` indicates how many bytes we should try to write.
/// `dest` is where the return value should be stored: number of bytes written, or `-1` in case of error.
///
/// When the write is done, `finish` will be called. Note that `write` itself may return before
/// that happens! Everything that should happen "after" the `write` needs to happen inside
/// `finish`.
fn write<'tcx>(
self: FileDescriptionRef<Self>,
_communicate_allowed: bool,
Expand Down
6 changes: 3 additions & 3 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
let val = this.read_scalar(val)?.to_i32()?;
let num = this.read_target_usize(num)?;
// The docs say val is "interpreted as unsigned char".
#[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
#[expect(clippy::as_conversions)]
let val = val as u8;

// C requires that this must always be a valid pointer (C18 §7.1.4).
Expand All @@ -665,7 +665,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
let val = this.read_scalar(val)?.to_i32()?;
let num = this.read_target_usize(num)?;
// The docs say val is "interpreted as unsigned char".
#[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
#[expect(clippy::as_conversions)]
let val = val as u8;

// C requires that this must always be a valid pointer (C18 §7.1.4).
Expand All @@ -676,7 +676,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
.iter()
.position(|&c| c == val);
if let Some(idx) = idx {
let new_ptr = ptr.wrapping_offset(Size::from_bytes(idx as u64), this);
let new_ptr = ptr.wrapping_offset(Size::from_bytes(idx), this);
this.write_pointer(new_ptr, dest)?;
} else {
this.write_null(dest)?;
Expand Down
Loading
Loading