Skip to content

Commit

Permalink
Rollup merge of rust-lang#132234 - RalfJung:miri-sync, r=RalfJung
Browse files Browse the repository at this point in the history
Miri subtree update

r? `@ghost`
  • Loading branch information
matthiaskrgr authored Oct 27, 2024
2 parents afd8897 + ca0e5df commit 0cace65
Show file tree
Hide file tree
Showing 37 changed files with 612 additions and 299 deletions.
44 changes: 19 additions & 25 deletions src/tools/miri/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
name: CI

on:
push:
# Run in PRs and for bors, but not on master.
branches:
- 'auto'
- 'try'
merge_group:
pull_request:
branches:
- 'master'
Expand Down Expand Up @@ -38,7 +34,7 @@ jobs:
# The `style` job only runs on Linux; this makes sure the Windows-host-specific
# code is also covered by clippy.
- name: Check clippy
if: matrix.os == 'windows-latest'
if: ${{ matrix.os == 'windows-latest' }}
run: ./miri clippy -- -D warnings

- name: Test Miri
Expand All @@ -62,27 +58,25 @@ jobs:
- name: rustdoc
run: RUSTDOCFLAGS="-Dwarnings" ./miri doc --document-private-items

# These jobs doesn't actually test anything, but they're only used to tell
# bors the build completed, as there is no practical way to detect when a
# workflow is successful listening to webhooks only.
#
# Summary job for the merge queue.
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
end-success:
name: bors build finished
runs-on: ubuntu-latest
# And they should be added below in `cron-fail-notify` as well.
conclusion:
needs: [build, style]
if: github.event.pusher.name == 'bors' && success()
steps:
- name: mark the job as a success
run: exit 0
end-failure:
name: bors build finished
# We need to ensure this job does *not* get skipped if its dependencies fail,
# because a skipped job is considered a success by GitHub. So we have to
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
# when the workflow is canceled manually.
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
needs: [build, style]
if: github.event.pusher.name == 'bors' && (failure() || cancelled())
steps:
- name: mark the job as a failure
run: exit 1
# Manually check the status of all dependencies. `if: failure()` does not work.
- name: Conclusion
run: |
# Print the dependent jobs to see them in the CI log
jq -C <<< '${{ toJson(needs) }}'
# Check if all jobs that we depend on (in the needs array) were successful.
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
cron-fail-notify:
name: cronjob failure notification
Expand All @@ -93,7 +87,7 @@ jobs:
# ... and create a PR.
pull-requests: write
needs: [build, style]
if: github.event_name == 'schedule' && failure()
if: ${{ github.event_name == 'schedule' && failure() }}
steps:
# Send a Zulip notification
- name: Install zulip-send
Expand Down Expand Up @@ -145,7 +139,7 @@ jobs:
git push -u origin $BRANCH
- name: Create Pull Request
run: |
PR=$(gh pr create -B master --title 'Automatic Rustup' --body '')
PR=$(gh pr create -B master --title 'Automatic Rustup' --body 'Please close and re-open this PR to trigger CI, then enable auto-merge.')
~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
--stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \
--message "A PR doing a rustc-pull [has been automatically created]($PR) for your convenience."
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ case $HOST_TARGET in
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap pthread --skip threadname
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap threadname pthread
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
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_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 @@
17a19e684cdf3ca088af8b4da6a6209d128913f4
814df6e50eaf89b90793e7d9618bb60f1f18377a
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,11 @@ impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> {
}

#[inline(never)] // This is only called on fatal code paths
pub(super) fn protector_error(&self, item: &Item, kind: ProtectorKind) -> InterpErrorKind<'tcx> {
pub(super) fn protector_error(
&self,
item: &Item,
kind: ProtectorKind,
) -> InterpErrorKind<'tcx> {
let protected = match kind {
ProtectorKind::WeakProtector => "weakly protected",
ProtectorKind::StrongProtector => "strongly protected",
Expand Down
30 changes: 30 additions & 0 deletions src/tools/miri/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(Scalar::from_bool(branch), dest)?;
}

"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f16()?;
let mode = match intrinsic_name {
"floorf16" => Round::TowardNegative,
"ceilf16" => Round::TowardPositive,
"truncf16" => Round::TowardZero,
"roundf16" => Round::NearestTiesToAway,
"rintf16" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f32()?;
Expand Down Expand Up @@ -175,6 +190,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => {
let [f] = check_arg_count(args)?;
let f = this.read_scalar(f)?.to_f128()?;
let mode = match intrinsic_name {
"floorf128" => Round::TowardNegative,
"ceilf128" => Round::TowardPositive,
"truncf128" => Round::TowardZero,
"roundf128" => Round::NearestTiesToAway,
"rintf128" => Round::NearestTiesToEven,
_ => bug!(),
};
let res = f.round_to_integral(mode).value;
let res = this.adjust_nan(res, &[f]);
this.write_scalar(res, dest)?;
}

#[rustfmt::skip]
| "sinf32"
Expand Down
11 changes: 4 additions & 7 deletions src/tools/miri/src/intrinsics/simd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use either::Either;
use rustc_apfloat::{Float, Round};
use rustc_middle::ty::FloatTy;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::{mir, ty, ty::FloatTy};
use rustc_middle::{mir, ty};
use rustc_span::{Symbol, sym};
use rustc_target::abi::{Endian, HasDataLayout};

Expand Down Expand Up @@ -630,12 +631,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let (right, right_len) = this.project_to_simd(right)?;
let (dest, dest_len) = this.project_to_simd(dest)?;

let index = generic_args[2]
.expect_const()
.try_to_valtree()
.unwrap()
.0
.unwrap_branch();
let index =
generic_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch();
let index_len = index.len();

assert_eq!(left_len, right_len);
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub use crate::range_map::RangeMap;
pub use crate::shims::EmulateItemResult;
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::{DynSym, EvalContextExt as _};
pub use crate::shims::io_error::{EvalContextExt as _, LibcError};
pub use crate::shims::io_error::{EvalContextExt as _, IoError, LibcError};
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
Expand Down
9 changes: 3 additions & 6 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else {
// If this does not fit in an isize, return null and, on Unix, set errno.
if this.target_os_is_unix() {
let einval = this.eval_libc("ENOMEM");
this.set_last_error(einval)?;
this.set_last_error(LibcError("ENOMEM"))?;
}
this.write_null(dest)?;
}
Expand All @@ -464,8 +463,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else {
// On size overflow, return null and, on Unix, set errno.
if this.target_os_is_unix() {
let einval = this.eval_libc("ENOMEM");
this.set_last_error(einval)?;
this.set_last_error(LibcError("ENOMEM"))?;
}
this.write_null(dest)?;
}
Expand All @@ -486,8 +484,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else {
// If this does not fit in an isize, return null and, on Unix, set errno.
if this.target_os_is_unix() {
let einval = this.eval_libc("ENOMEM");
this.set_last_error(einval)?;
this.set_last_error(LibcError("ENOMEM"))?;
}
this.write_null(dest)?;
}
Expand Down
10 changes: 10 additions & 0 deletions src/tools/miri/src/shims/io_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
interp_ok(Scalar::from_i32(-1))
}

/// Sets the last OS error and return `-1` as a `i64`-typed Scalar
fn set_last_error_and_return_i64(
&mut self,
err: impl Into<IoError>,
) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();
this.set_last_error(err)?;
interp_ok(Scalar::from_i64(-1))
}

/// Gets the last error variable.
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();
Expand Down
12 changes: 3 additions & 9 deletions src/tools/miri/src/shims/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else if relative_clocks.contains(&clk_id) {
this.machine.clock.now().duration_since(this.machine.clock.epoch())
} else {
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return interp_ok(Scalar::from_i32(-1));
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
};

let tv_sec = duration.as_secs();
Expand All @@ -109,9 +107,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Using tz is obsolete and should always be null
let tz = this.read_pointer(tz_op)?;
if !this.ptr_is_null(tz)? {
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return interp_ok(Scalar::from_i32(-1));
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
}

let duration = system_time_to_duration(&SystemTime::now())?;
Expand Down Expand Up @@ -323,9 +319,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let duration = match this.read_timespec(&req)? {
Some(duration) => duration,
None => {
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return interp_ok(Scalar::from_i32(-1));
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/tools/miri/src/shims/unix/android/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_span::Symbol;
use rustc_target::spec::abi::Abi;

use crate::shims::unix::android::thread::prctl;
use crate::*;

pub fn is_dyn_sym(_name: &str) -> bool {
Expand All @@ -25,6 +26,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}

// Threading
"prctl" => prctl(this, link_name, abi, args, dest)?,

_ => return interp_ok(EmulateItemResult::NotSupported),
}
interp_ok(EmulateItemResult::NeedsReturn)
Expand Down
1 change: 1 addition & 0 deletions src/tools/miri/src/shims/unix/android/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod foreign_items;
pub mod thread;
57 changes: 57 additions & 0 deletions src/tools/miri/src/shims/unix/android/thread.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use rustc_span::Symbol;
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;

use crate::helpers::check_min_arg_count;
use crate::shims::unix::thread::EvalContextExt as _;
use crate::*;

const TASK_COMM_LEN: usize = 16;

pub fn prctl<'tcx>(
this: &mut MiriInterpCx<'tcx>,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
// We do not use `check_shim` here because `prctl` is variadic. The argument
// count is checked bellow.
this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;

// FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
let pr_set_name = 15;
let pr_get_name = 16;

let [op] = check_min_arg_count("prctl", args)?;
let res = match this.read_scalar(op)?.to_i32()? {
op if op == pr_set_name => {
let [_, name] = check_min_arg_count("prctl(PR_SET_NAME, ...)", args)?;
let name = this.read_scalar(name)?;
let thread = this.pthread_self()?;
// The Linux kernel silently truncates long names.
// https://www.man7.org/linux/man-pages/man2/PR_SET_NAME.2const.html
let res =
this.pthread_setname_np(thread, name, TASK_COMM_LEN, /* truncate */ true)?;
assert!(res);
Scalar::from_u32(0)
}
op if op == pr_get_name => {
let [_, name] = check_min_arg_count("prctl(PR_GET_NAME, ...)", args)?;
let name = this.read_scalar(name)?;
let thread = this.pthread_self()?;
let len = Scalar::from_target_usize(TASK_COMM_LEN as u64, this);
this.check_ptr_access(
name.to_pointer(this)?,
Size::from_bytes(TASK_COMM_LEN),
CheckInAllocMsg::MemoryAccessTest,
)?;
let res = this.pthread_getname_np(thread, name, len, /* truncate*/ false)?;
assert!(res);
Scalar::from_u32(0)
}
op => throw_unsup_format!("Miri does not support `prctl` syscall with op={}", op),
};
this.write_scalar(res, dest)?;
interp_ok(())
}
Loading

0 comments on commit 0cace65

Please sign in to comment.