about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--library/std/src/sys/unix/time.rs4
-rw-r--r--src/tools/miri/Cargo.lock7
-rw-r--r--src/tools/miri/Cargo.toml1
-rw-r--r--src/tools/miri/README.md9
-rwxr-xr-xsrc/tools/miri/miri44
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/bin/miri.rs7
-rw-r--r--src/tools/miri/src/shims/mod.rs6
-rw-r--r--src/tools/miri/src/shims/time.rs48
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs6
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs9
-rw-r--r--src/tools/miri/src/stacked_borrows/mod.rs97
-rwxr-xr-xsrc/tools/miri/test-cargo-miri/run-test.py2
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-misc.rs20
-rw-r--r--src/tools/miri/tests/pass/align_offset_symbolic.rs6
-rw-r--r--src/tools/miri/tests/pass/panic/catch_panic.rs2
17 files changed, 154 insertions, 117 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 87a4124e7db..267fa69485c 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 ffcc507d2a7..d5abd9b581c 100644
--- a/library/std/src/sys/unix/time.rs
+++ b/library/std/src/sys/unix/time.rs
@@ -150,7 +150,7 @@ impl From<libc::timespec> 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 3c890df08cc..15fc89b8681 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",
 ]
@@ -633,12 +632,6 @@ dependencies = [
 ]
 
 [[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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 65ef92e21d6..0f69a0baef4 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 e9738cbc515..dac0a9820b9 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=<blocks>`, which prints the report every N basic
   blocks.
-* `-Zmiri-seed=<hex>` configures the seed of the RNG that Miri uses to resolve non-determinism. This
+* `-Zmiri-seed=<num>` 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 b09897c294c..38d36898768 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 <commit>:
+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 <github user> <branch>:
 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 746fcb2e183..d007f952a67 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 e673ea67dbc..ffe89921d98 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::<u64>().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 dcb99a27668..b6efad6b5ee 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 617f90dfaa5..bc0b71fbc20 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 44a433df1e9..d746f9df90a 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 2b53152688b..34076e842d5 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 9ce02a02ec4..f2e2df5ad08 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 c611b9c44be..46b3afa70e5 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 904ae2fb17f..2a4300fcd04 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::<libc::timespec>::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 b3e57338363..4e1584b8387 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 30890440653..5d57df4e52b 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 {}
     });