diff --git a/Cargo.lock b/Cargo.lock index 87a4124e7db01..267fa69485cf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2330,7 +2330,6 @@ dependencies = [ "regex", "rustc-workspace-hack", "rustc_version", - "shell-escape", "smallvec", "ui_test", ] diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index ffcc507d2a763..d5abd9b581c65 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -150,7 +150,7 @@ impl From for Timespec { } #[cfg(any( - all(target_os = "macos", any(not(target_arch = "aarch64"), miri)), + all(target_os = "macos", any(not(target_arch = "aarch64"))), target_os = "ios", target_os = "watchos" ))] @@ -270,7 +270,7 @@ mod inner { } #[cfg(not(any( - all(target_os = "macos", any(not(target_arch = "aarch64"), miri)), + all(target_os = "macos", any(not(target_arch = "aarch64"))), target_os = "ios", target_os = "watchos" )))] diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 3c890df08cc26..15fc89b86818a 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -383,7 +383,6 @@ dependencies = [ "regex", "rustc-workspace-hack", "rustc_version", - "shell-escape", "smallvec", "ui_test", ] @@ -632,12 +631,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shell-escape" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" - [[package]] name = "smallvec" version = "1.9.0" diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 65ef92e21d6b1..0f69a0baef4fb 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -21,7 +21,6 @@ doctest = false # and no doc tests getrandom = { version = "0.2", features = ["std"] } env_logger = "0.9" log = "0.4" -shell-escape = "0.1.4" rand = "0.8" smallvec = "1.7" diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index e9738cbc515ff..dac0a9820b90e 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -1,10 +1,5 @@ # Miri -[![Actions build status][actions-badge]][actions-url] - -[actions-badge]: https://github.com/rust-lang/miri/workflows/CI/badge.svg?branch=master -[actions-url]: https://github.com/rust-lang/miri/actions - An experimental interpreter for [Rust][rust]'s [mid-level intermediate representation][mir] (MIR). It can run binaries and test suites of cargo projects and detect certain classes of @@ -200,7 +195,7 @@ randomness that is used to determine allocation base addresses. The following snippet calls Miri in a loop with different values for the seed: ``` -for SEED in $({ echo obase=16; seq 0 255; } | bc); do +for SEED in $(seq 0 255); do echo "Trying seed: $SEED" MIRIFLAGS=-Zmiri-seed=$SEED cargo miri test || { echo "Failing seed: $SEED"; break; }; done @@ -308,7 +303,7 @@ environment variable. We first document the most relevant and most commonly used tell what it is doing when a program just keeps running. You can customize how frequently the report is printed via `-Zmiri-report-progress=`, which prints the report every N basic blocks. -* `-Zmiri-seed=` configures the seed of the RNG that Miri uses to resolve non-determinism. This +* `-Zmiri-seed=` configures the seed of the RNG that Miri uses to resolve non-determinism. This RNG is used to pick base addresses for allocations, to determine preemption and failure of `compare_exchange_weak`, and to control store buffering for weak memory emulation. When isolation is enabled (the default), this is also used to emulate system entropy. The default seed is 0. You diff --git a/src/tools/miri/miri b/src/tools/miri/miri index b09897c294cd1..38d36898768e1 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -48,10 +48,10 @@ Update and activate the rustup toolchain 'miri' to the commit given in the `rustup-toolchain-install-master` must be installed for this to work. Any extra flags are passed to `rustup-toolchain-install-master`. -./miri rustc-pull: -Pull and merge Miri changes from the rustc repo. The fetched commit is stored in -the `rust-version` file, so the next `./miri toolchain` will install the rustc -we just pulled. +./miri rustc-pull : +Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest +rustc commit. The fetched commit is stored in the `rust-version` file, so the +next `./miri toolchain` will install the rustc that just got pulled. ./miri rustc-push : Push Miri changes back to the rustc repo. This will pull a copy of the rustc @@ -113,18 +113,17 @@ toolchain) ;; rustc-pull) cd "$MIRIDIR" - FETCH_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) - # We can't pull from a commit with josh - # (https://github.com/josh-project/josh/issues/1034), so we just hope that - # nothing gets merged into rustc *during* this pull. - git fetch http://localhost:8000/rust-lang/rust.git$JOSH_FILTER.git master - # Just verify that `master` didn't move. - if [[ $FETCH_COMMIT != $(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) ]]; then - echo "Looks like something got merged into Rust *while we were pulling*. Aborting. Please try again." + FETCH_COMMIT="$1" + if [ -z "$FETCH_COMMIT" ]; then + FETCH_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) fi - echo "$FETCH_COMMIT" > rust-version # do this *before* merging as merging will fail in case of conflicts + # Update rust-version file. As a separate commit, since making it part of + # the merge has confused the heck out of josh in the past. + echo "$FETCH_COMMIT" > rust-version + git commit rust-version -m "Preparing for merge from rustc" + # Fetch given rustc commit and note down which one that was + git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git git merge FETCH_HEAD --no-ff -m "Merge from rustc" - git commit rust-version --amend -m "Merge from rustc" exit 0 ;; rustc-push) @@ -157,16 +156,27 @@ rustc-push) fi git fetch https://github.com/rust-lang/rust $BASE git push https://github.com/$USER/rust $BASE:refs/heads/$BRANCH -f + echo # Do the actual push. cd "$MIRIDIR" echo "Pushing Miri changes..." git push http://localhost:8000/$USER/rust.git$JOSH_FILTER.git HEAD:$BRANCH - exit 0 + # Do a round-trip check to make sure the push worked as expected. + echo + git fetch http://localhost:8000/$USER/rust.git@$JOSH_FILTER.git $BRANCH &>/dev/null + if [[ $(git rev-parse HEAD) != $(git rev-parse FETCH_HEAD) ]]; then + echo "ERROR: Josh created a non-roundtrip push! Do NOT merge this into rustc!" + exit 1 + else + echo "Confirmed that the push round-trips back to Miri properly. Please create a rustc PR:" + echo " https://github.com/$USER/rust/pull/new/$BRANCH" + exit 0 + fi ;; many-seeds) - for SEED in $({ echo obase=16; seq 0 255; } | bc); do + for SEED in $(seq 0 255); do echo "Trying seed: $SEED" - MIRIFLAGS="$MIRIFLAGS -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; } + MIRIFLAGS="$MIRIFLAGS -Zlayout-seed=$SEED -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; } done exit 0 ;; diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 746fcb2e183c6..d007f952a67a1 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -101e1822c3e54e63996c8aaa014d55716f3937eb +7477c1f4f7d6bef037d523099b240d22aa1b63a0 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index e673ea67dbc5b..ffe89921d9866 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -394,10 +394,9 @@ fn main() { if miri_config.seed.is_some() { show_error!("Cannot specify -Zmiri-seed multiple times!"); } - let seed = u64::from_str_radix(param, 16) - .unwrap_or_else(|_| show_error!( - "-Zmiri-seed should only contain valid hex digits [0-9a-fA-F] and must fit into a u64 (max 16 characters)" - )); + let seed = param.parse::().unwrap_or_else(|_| { + show_error!("-Zmiri-seed must be an integer that fits into u64") + }); miri_config.seed = Some(seed); } else if let Some(_param) = arg.strip_prefix("-Zmiri-env-exclude=") { show_error!( diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index dcb99a2766826..b6efad6b5ee08 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -89,6 +89,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } let ptr = this.read_pointer(ptr_op)?; + // If this carries no provenance, treat it like an integer. + if ptr.provenance.is_none() { + // Use actual implementation. + return Ok(false); + } + if let Ok((alloc_id, _offset, _)) = this.ptr_try_get_alloc_id(ptr) { // Only do anything if we can identify the allocation this goes to. let (_size, cur_align, _kind) = this.get_alloc_info(alloc_id); diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index 617f90dfaa59f..bc0b71fbc2096 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -22,21 +22,44 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); - this.assert_target_os("linux", "clock_gettime"); + this.assert_target_os_is_unix("clock_gettime"); let clk_id = this.read_scalar(clk_id_op)?.to_i32()?; - // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the - // Unix epoch, including effects which may cause time to move backwards such as NTP. - // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version - // is just specified to be "faster and less precise", so we implement both the same way. - let absolute_clocks = - [this.eval_libc_i32("CLOCK_REALTIME")?, this.eval_libc_i32("CLOCK_REALTIME_COARSE")?]; - // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are - // never allowed to go backwards. We don't need to do any additonal monotonicity - // enforcement because std::time::Instant already guarantees that it is monotonic. - let relative_clocks = - [this.eval_libc_i32("CLOCK_MONOTONIC")?, this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?]; + let absolute_clocks; + let mut relative_clocks; + + match this.tcx.sess.target.os.as_ref() { + "linux" => { + // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the + // Unix epoch, including effects which may cause time to move backwards such as NTP. + // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version + // is just specified to be "faster and less precise", so we implement both the same way. + absolute_clocks = vec![ + this.eval_libc_i32("CLOCK_REALTIME")?, + this.eval_libc_i32("CLOCK_REALTIME_COARSE")?, + ]; + // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are + // never allowed to go backwards. We don't need to do any additonal monotonicity + // enforcement because std::time::Instant already guarantees that it is monotonic. + relative_clocks = vec![ + this.eval_libc_i32("CLOCK_MONOTONIC")?, + this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?, + ]; + } + "macos" => { + absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")?]; + relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")?]; + // Some clocks only seem to exist in the aarch64 version of the target. + if this.tcx.sess.target.arch == "aarch64" { + // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but + // that's not really something a program running inside Miri can tell, anyway. + // We need to support it because std uses it. + relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW")?); + } + } + target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"), + } let duration = if absolute_clocks.contains(&clk_id) { this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?; @@ -44,6 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } else if relative_clocks.contains(&clk_id) { this.machine.clock.now().duration_since(this.machine.clock.anchor()) } else { + // Unsupported clock. let einval = this.eval_libc("EINVAL")?; this.set_last_error(einval)?; return Ok(Scalar::from_i32(-1)); diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 44a433df1e9c0..d746f9df90ac3 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -180,6 +180,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let result = this.gettimeofday(tv, tz)?; this.write_scalar(Scalar::from_i32(result), dest)?; } + "clock_gettime" => { + let [clk_id, tp] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let result = this.clock_gettime(clk_id, tp)?; + this.write_scalar(result, dest)?; + } // Allocation "posix_memalign" => { diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 2b53152688bb7..34076e842d55b 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -43,15 +43,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_scalar(result, dest)?; } - // Time related shims - "clock_gettime" => { - // This is a POSIX function but it has only been tested on linux. - let [clk_id, tp] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let result = this.clock_gettime(clk_id, tp)?; - this.write_scalar(result, dest)?; - } - // Threading "pthread_condattr_setclock" => { let [attr, clock_id] = diff --git a/src/tools/miri/src/stacked_borrows/mod.rs b/src/tools/miri/src/stacked_borrows/mod.rs index 9ce02a02ec408..f2e2df5ad0800 100644 --- a/src/tools/miri/src/stacked_borrows/mod.rs +++ b/src/tools/miri/src/stacked_borrows/mod.rs @@ -14,7 +14,6 @@ use rustc_middle::mir::RetagKind; use rustc_middle::ty::{ self, layout::{HasParamEnv, LayoutOf}, - Ty, }; use rustc_target::abi::Abi; use rustc_target::abi::Size; @@ -983,28 +982,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields }; return visitor.visit_value(place); - // Determine mutability and whether to add a protector. - // Cannot use `builtin_deref` because that reports *immutable* for `Box`, - // making it useless. - fn qualify(ty: Ty<'_>, kind: RetagKind) -> Option<(RefKind, bool)> { - match ty.kind() { - // References are simple. - ty::Ref(_, _, Mutability::Mut) => - Some(( - RefKind::Unique { two_phase: kind == RetagKind::TwoPhase }, - kind == RetagKind::FnEntry, - )), - ty::Ref(_, _, Mutability::Not) => - Some((RefKind::Shared, kind == RetagKind::FnEntry)), - // Raw pointers need to be enabled. - ty::RawPtr(tym) if kind == RetagKind::Raw => - Some((RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, false)), - // Boxes are handled separately due to that allocator situation, - // see the visitor below. - _ => None, - } - } - // The actual visitor. struct RetagVisitor<'ecx, 'mir, 'tcx> { ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>, @@ -1057,34 +1034,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(()); } - let recurse_for_fields = || { - match self.retag_fields { - RetagFields::No => false, - RetagFields::Yes => true, - RetagFields::OnlyScalar => { - // Matching `ArgAbi::new` at the time of writing, only fields of - // `Scalar` and `ScalarPair` ABI are considered. - matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..)) + // Check the type of this value to see what to do with it (retag, or recurse). + match place.layout.ty.kind() { + ty::Ref(_, _, mutbl) => { + let ref_kind = match mutbl { + Mutability::Mut => + RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase }, + Mutability::Not => RefKind::Shared, + }; + self.retag_place( + place, + ref_kind, + self.retag_cause, + /*protector*/ self.kind == RetagKind::FnEntry, + )?; + } + ty::RawPtr(tym) => { + // We definitely do *not* want to recurse into raw pointers -- wide raw + // pointers have fields, and for dyn Trait pointees those can have reference + // type! + if self.kind == RetagKind::Raw { + // Raw pointers need to be enabled. + self.retag_place( + place, + RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, + self.retag_cause, + /*protector*/ false, + )?; + } + } + _ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => { + // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above. + // (Yes this means we technically also recursively retag the allocator itself + // even if field retagging is not enabled. *shrug*) + self.walk_value(place)?; + } + _ => { + // Not a reference/pointer/box. Only recurse if configured appropriately. + let recurse = match self.retag_fields { + RetagFields::No => false, + RetagFields::Yes => true, + RetagFields::OnlyScalar => { + // Matching `ArgAbi::new` at the time of writing, only fields of + // `Scalar` and `ScalarPair` ABI are considered. + matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..)) + } + }; + if recurse { + self.walk_value(place)?; } } - }; - - if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) { - self.retag_place(place, ref_kind, self.retag_cause, protector)?; - } else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) { - // Wide raw pointers *do* have fields and their types are strange. - // vtables have a type like `&[*const (); 3]` or so! - // Do *not* recurse into them. - // (No need to worry about wide references, those always "qualify". And Boxes - // are handles specially by the visitor anyway.) - } else if recurse_for_fields() - || place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) - { - // Recurse deeper. Need to always recurse for `Box` to even hit `visit_box`. - // (Yes this means we technically also recursively retag the allocator itself - // even if field retagging is not enabled. *shrug*) - self.walk_value(place)?; } + Ok(()) } } diff --git a/src/tools/miri/test-cargo-miri/run-test.py b/src/tools/miri/test-cargo-miri/run-test.py index c611b9c44be9d..46b3afa70e5b0 100755 --- a/src/tools/miri/test-cargo-miri/run-test.py +++ b/src/tools/miri/test-cargo-miri/run-test.py @@ -133,7 +133,7 @@ def test_cargo_miri_test(): test("`cargo miri test`", cargo_miri("test"), default_ref, "test.stderr-empty.ref", - env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=feed"}, + env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=4242"}, ) test("`cargo miri test` (no isolation, no doctests)", cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml` diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs index 904ae2fb17f9b..2a4300fcd049e 100644 --- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs +++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs @@ -181,17 +181,25 @@ fn test_thread_local_errno() { } /// Tests whether clock support exists at all -#[cfg(target_os = "linux")] fn test_clocks() { let mut tp = std::mem::MaybeUninit::::uninit(); let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) }; assert_eq!(is_error, 0); - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) }; assert_eq!(is_error, 0); - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); + #[cfg(target_os = "linux")] + { + let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + let is_error = + unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + } + #[cfg(all(target_os = "macos", target_arch = "aarch64"))] + { + let is_error = unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + } } fn test_posix_gettimeofday() { @@ -293,11 +301,11 @@ fn main() { test_thread_local_errno(); test_isatty(); + test_clocks(); #[cfg(target_os = "linux")] { test_posix_fadvise(); test_sync_file_range(); - test_clocks(); } } diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.rs b/src/tools/miri/tests/pass/align_offset_symbolic.rs index b3e5733836390..4e1584b838714 100644 --- a/src/tools/miri/tests/pass/align_offset_symbolic.rs +++ b/src/tools/miri/tests/pass/align_offset_symbolic.rs @@ -1,4 +1,7 @@ //@compile-flags: -Zmiri-symbolic-alignment-check +#![feature(strict_provenance)] + +use std::ptr; fn test_align_offset() { let d = Box::new([0u32; 4]); @@ -16,6 +19,9 @@ fn test_align_offset() { assert_eq!(raw.wrapping_offset(2).align_offset(2), 0); assert_eq!(raw.wrapping_offset(2).align_offset(4), 2); assert_eq!(raw.wrapping_offset(2).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment + + let p = ptr::invalid::<()>(1); + assert_eq!(p.align_offset(1), 0); } fn test_align_to() { diff --git a/src/tools/miri/tests/pass/panic/catch_panic.rs b/src/tools/miri/tests/pass/panic/catch_panic.rs index 308904406538c..5d57df4e52bfa 100644 --- a/src/tools/miri/tests/pass/panic/catch_panic.rs +++ b/src/tools/miri/tests/pass/panic/catch_panic.rs @@ -69,7 +69,7 @@ fn main() { }); test(Some("align_offset: align is not a power-of-two"), |_old_val| { - (0usize as *const u8).align_offset(3); + let _ = (0usize as *const u8).align_offset(3); loop {} });