mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #106023 - JohnTitor:rollup-k8mettz, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #105584 (add assert messages if chunks/windows are length 0) - #105602 (interpret: add read_machine_[ui]size convenience methods) - #105824 (str.lines() docstring: clarify that line endings are not returned) - #105980 (Refer to "Waker" rather than "RawWaker" in `drop` comment) - #105986 (Fix typo in reading_half_a_pointer.rs) - #105995 (Add regression test for #96530) - #106008 (Sort lint_groups in no_lint_suggestion) - #106014 (Add comment explaining what the scrape-examples-toggle.goml GUI test is about) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
8574880108
@ -303,7 +303,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
sym::offset => {
|
||||
let ptr = self.read_pointer(&args[0])?;
|
||||
let offset_count = self.read_scalar(&args[1])?.to_machine_isize(self)?;
|
||||
let offset_count = self.read_machine_isize(&args[1])?;
|
||||
let pointee_ty = substs.type_at(0);
|
||||
|
||||
let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
|
||||
@ -311,7 +311,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
sym::arith_offset => {
|
||||
let ptr = self.read_pointer(&args[0])?;
|
||||
let offset_count = self.read_scalar(&args[1])?.to_machine_isize(self)?;
|
||||
let offset_count = self.read_machine_isize(&args[1])?;
|
||||
let pointee_ty = substs.type_at(0);
|
||||
|
||||
let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
|
||||
@ -670,7 +670,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>,
|
||||
nonoverlapping: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
|
||||
let count = self.read_machine_usize(&count)?;
|
||||
let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?;
|
||||
let (size, align) = (layout.size, layout.align.abi);
|
||||
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
|
||||
@ -698,7 +698,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
||||
let dst = self.read_pointer(&dst)?;
|
||||
let byte = self.read_scalar(&byte)?.to_u8()?;
|
||||
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
|
||||
let count = self.read_machine_usize(&count)?;
|
||||
|
||||
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
|
||||
// but no actual allocation can be big enough for the difference to be noticeable.
|
||||
|
@ -404,6 +404,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
Ok(self.read_immediate(op)?.to_scalar())
|
||||
}
|
||||
|
||||
// Pointer-sized reads are fairly common and need target layout access, so we wrap them in
|
||||
// convenience functions.
|
||||
|
||||
/// Read a pointer from a place.
|
||||
pub fn read_pointer(
|
||||
&self,
|
||||
@ -411,6 +414,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
|
||||
self.read_scalar(op)?.to_pointer(self)
|
||||
}
|
||||
/// Read a pointer-sized unsigned integer from a place.
|
||||
pub fn read_machine_usize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, u64> {
|
||||
self.read_scalar(op)?.to_machine_usize(self)
|
||||
}
|
||||
/// Read a pointer-sized signed integer from a place.
|
||||
pub fn read_machine_isize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, i64> {
|
||||
self.read_scalar(op)?.to_machine_isize(self)
|
||||
}
|
||||
|
||||
/// Turn the wide MPlace into a string (must already be dereferenced!)
|
||||
pub fn read_str(&self, mplace: &MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx, &str> {
|
||||
|
@ -363,7 +363,7 @@ where
|
||||
Index(local) => {
|
||||
let layout = self.layout_of(self.tcx.types.usize)?;
|
||||
let n = self.local_to_op(self.frame(), local, Some(layout))?;
|
||||
let n = self.read_scalar(&n)?.to_machine_usize(self)?;
|
||||
let n = self.read_machine_usize(&n)?;
|
||||
self.place_index(base, n)?
|
||||
}
|
||||
ConstantIndex { offset, min_length, from_end } => {
|
||||
@ -392,7 +392,7 @@ where
|
||||
Index(local) => {
|
||||
let layout = self.layout_of(self.tcx.types.usize)?;
|
||||
let n = self.local_to_op(self.frame(), local, Some(layout))?;
|
||||
let n = self.read_scalar(&n)?.to_machine_usize(self)?;
|
||||
let n = self.read_machine_usize(&n)?;
|
||||
self.operand_index(base, n)?
|
||||
}
|
||||
ConstantIndex { offset, min_length, from_end } => {
|
||||
|
@ -483,7 +483,16 @@ impl LintStore {
|
||||
return CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)));
|
||||
}
|
||||
// ...if not, search for lints with a similar name
|
||||
let groups = self.lint_groups.keys().copied().map(Symbol::intern);
|
||||
// Note: find_best_match_for_name depends on the sort order of its input vector.
|
||||
// To ensure deterministic output, sort elements of the lint_groups hash map.
|
||||
// Also, never suggest deprecated lint groups.
|
||||
let mut groups: Vec<_> = self
|
||||
.lint_groups
|
||||
.iter()
|
||||
.filter_map(|(k, LintGroup { depr, .. })| if depr.is_none() { Some(k) } else { None })
|
||||
.collect();
|
||||
groups.sort();
|
||||
let groups = groups.iter().map(|k| Symbol::intern(k));
|
||||
let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower()));
|
||||
let names: Vec<Symbol> = groups.chain(lints).collect();
|
||||
let suggestion = find_best_match_for_name(&names, Symbol::intern(&name_lower), None);
|
||||
|
@ -893,7 +893,7 @@ impl<T> [T] {
|
||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
||||
#[inline]
|
||||
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
|
||||
assert_ne!(chunk_size, 0);
|
||||
assert_ne!(chunk_size, 0, "chunks cannot have a size of zero");
|
||||
ChunksExact::new(self, chunk_size)
|
||||
}
|
||||
|
||||
@ -935,7 +935,7 @@ impl<T> [T] {
|
||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
||||
#[inline]
|
||||
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
|
||||
assert_ne!(chunk_size, 0);
|
||||
assert_ne!(chunk_size, 0, "chunks cannot have a size of zero");
|
||||
ChunksExactMut::new(self, chunk_size)
|
||||
}
|
||||
|
||||
@ -1017,7 +1017,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "chunks cannot have a size of zero");
|
||||
let len = self.len() / N;
|
||||
let (multiple_of_n, remainder) = self.split_at(len * N);
|
||||
// SAFETY: We already panicked for zero, and ensured by construction
|
||||
@ -1048,7 +1048,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]]) {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "chunks cannot have a size of zero");
|
||||
let len = self.len() / N;
|
||||
let (remainder, multiple_of_n) = self.split_at(self.len() - len * N);
|
||||
// SAFETY: We already panicked for zero, and ensured by construction
|
||||
@ -1087,7 +1087,7 @@ impl<T> [T] {
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
#[inline]
|
||||
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "chunks cannot have a size of zero");
|
||||
ArrayChunks::new(self)
|
||||
}
|
||||
|
||||
@ -1166,7 +1166,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "chunks cannot have a size of zero");
|
||||
let len = self.len() / N;
|
||||
let (multiple_of_n, remainder) = self.split_at_mut(len * N);
|
||||
// SAFETY: We already panicked for zero, and ensured by construction
|
||||
@ -1203,7 +1203,7 @@ impl<T> [T] {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]]) {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "chunks cannot have a size of zero");
|
||||
let len = self.len() / N;
|
||||
let (remainder, multiple_of_n) = self.split_at_mut(self.len() - len * N);
|
||||
// SAFETY: We already panicked for zero, and ensured by construction
|
||||
@ -1244,7 +1244,7 @@ impl<T> [T] {
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
#[inline]
|
||||
pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "chunks cannot have a size of zero");
|
||||
ArrayChunksMut::new(self)
|
||||
}
|
||||
|
||||
@ -1276,7 +1276,7 @@ impl<T> [T] {
|
||||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
#[inline]
|
||||
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
|
||||
assert_ne!(N, 0);
|
||||
assert_ne!(N, 0, "windows cannot have a size of zero");
|
||||
ArrayWindows::new(self)
|
||||
}
|
||||
|
||||
|
@ -970,8 +970,10 @@ impl str {
|
||||
|
||||
/// An iterator over the lines of a string, as string slices.
|
||||
///
|
||||
/// Lines are ended with either a newline (`\n`) or a carriage return with
|
||||
/// a line feed (`\r\n`).
|
||||
/// Lines are split at line endings that are either newlines (`\n`) or
|
||||
/// sequences of a carriage return followed by a line feed (`\r\n`).
|
||||
///
|
||||
/// Line terminators are not included in the lines returned by the iterator.
|
||||
///
|
||||
/// The final line ending is optional. A string that ends with a final line
|
||||
/// ending will return the same lines as an otherwise identical string
|
||||
|
@ -104,7 +104,7 @@ pub struct RawWakerVTable {
|
||||
/// pointer.
|
||||
wake_by_ref: unsafe fn(*const ()),
|
||||
|
||||
/// This function gets called when a [`RawWaker`] gets dropped.
|
||||
/// This function gets called when a [`Waker`] gets dropped.
|
||||
///
|
||||
/// The implementation of this function must make sure to release any
|
||||
/// resources that are associated with this instance of a [`RawWaker`] and
|
||||
@ -151,7 +151,7 @@ impl RawWakerVTable {
|
||||
///
|
||||
/// # `drop`
|
||||
///
|
||||
/// This function gets called when a [`RawWaker`] gets dropped.
|
||||
/// This function gets called when a [`Waker`] gets dropped.
|
||||
///
|
||||
/// The implementation of this function must make sure to release any
|
||||
/// resources that are associated with this instance of a [`RawWaker`] and
|
||||
|
@ -1,3 +1,4 @@
|
||||
// This tests checks that the "scraped examples" toggle is working as expected.
|
||||
goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
|
||||
|
||||
// Clicking "More examples..." will open additional examples
|
||||
|
20
src/test/ui/typeck/issue-96530.rs
Normal file
20
src/test/ui/typeck/issue-96530.rs
Normal file
@ -0,0 +1,20 @@
|
||||
struct Person {
|
||||
first_name: String,
|
||||
age: u32,
|
||||
}
|
||||
|
||||
fn first_woman(man: &Person) -> Person {
|
||||
Person {
|
||||
first_name: "Eve".to_string(),
|
||||
..man.clone() //~ ERROR: mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let adam = Person {
|
||||
first_name: "Adam".to_string(),
|
||||
age: 0,
|
||||
};
|
||||
|
||||
let eve = first_woman(&adam);
|
||||
}
|
9
src/test/ui/typeck/issue-96530.stderr
Normal file
9
src/test/ui/typeck/issue-96530.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-96530.rs:9:11
|
||||
|
|
||||
LL | ..man.clone()
|
||||
| ^^^^^^^^^^^ expected struct `Person`, found `&Person`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -233,7 +233,7 @@ impl MainThreadState {
|
||||
this.machine.main_fn_ret_place.unwrap().ptr,
|
||||
this.machine.layouts.isize,
|
||||
);
|
||||
let exit_code = this.read_scalar(&ret_place.into())?.to_machine_isize(this)?;
|
||||
let exit_code = this.read_machine_isize(&ret_place.into())?;
|
||||
// Need to call this ourselves since we are not going to return to the scheduler
|
||||
// loop, and we want the main thread TLS to not show up as memory leaks.
|
||||
this.terminate_active_thread()?;
|
||||
|
@ -321,7 +321,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
this.assert_target_os_is_unix("getcwd");
|
||||
|
||||
let buf = this.read_pointer(buf_op)?;
|
||||
let size = this.read_scalar(size_op)?.to_machine_usize(&*this.tcx)?;
|
||||
let size = this.read_machine_usize(size_op)?;
|
||||
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
this.reject_in_isolation("`getcwd`", reject_with)?;
|
||||
|
@ -485,14 +485,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// Standard C allocation
|
||||
"malloc" => {
|
||||
let [size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
"calloc" => {
|
||||
let [items, len] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let items = this.read_scalar(items)?.to_machine_usize(this)?;
|
||||
let len = this.read_scalar(len)?.to_machine_usize(this)?;
|
||||
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 res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C)?;
|
||||
@ -506,7 +506,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"realloc" => {
|
||||
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_scalar(new_size)?.to_machine_usize(this)?;
|
||||
let new_size = this.read_machine_usize(new_size)?;
|
||||
let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
@ -514,8 +514,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// Rust allocation
|
||||
"__rust_alloc" | "miri_alloc" => {
|
||||
let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let align = this.read_scalar(align)?.to_machine_usize(this)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
|
||||
let default = |this: &mut MiriInterpCx<'mir, 'tcx>| {
|
||||
Self::check_alloc_request(size, align)?;
|
||||
@ -546,8 +546,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
"__rust_alloc_zeroed" => {
|
||||
let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let align = this.read_scalar(align)?.to_machine_usize(this)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
|
||||
return this.emulate_allocator(Symbol::intern("__rg_alloc_zeroed"), |this| {
|
||||
Self::check_alloc_request(size, align)?;
|
||||
@ -566,8 +566,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"__rust_dealloc" | "miri_dealloc" => {
|
||||
let [ptr, old_size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let old_size = this.read_scalar(old_size)?.to_machine_usize(this)?;
|
||||
let align = this.read_scalar(align)?.to_machine_usize(this)?;
|
||||
let old_size = this.read_machine_usize(old_size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
|
||||
let default = |this: &mut MiriInterpCx<'mir, 'tcx>| {
|
||||
let memory_kind = match link_name.as_str() {
|
||||
@ -596,9 +596,9 @@ 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 = this.read_pointer(ptr)?;
|
||||
let old_size = this.read_scalar(old_size)?.to_machine_usize(this)?;
|
||||
let align = this.read_scalar(align)?.to_machine_usize(this)?;
|
||||
let new_size = this.read_scalar(new_size)?.to_machine_usize(this)?;
|
||||
let old_size = this.read_machine_usize(old_size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let new_size = this.read_machine_usize(new_size)?;
|
||||
// No need to check old_size; we anyway check that they match the allocation.
|
||||
|
||||
return this.emulate_allocator(Symbol::intern("__rg_realloc"), |this| {
|
||||
@ -621,7 +621,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
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_scalar(n)?.to_machine_usize(this)?);
|
||||
let n = Size::from_bytes(this.read_machine_usize(n)?);
|
||||
|
||||
let result = {
|
||||
let left_bytes = this.read_bytes_ptr_strip_provenance(left, n)?;
|
||||
@ -641,7 +641,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
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_scalar(num)?.to_machine_usize(this)?;
|
||||
let num = this.read_machine_usize(num)?;
|
||||
// The docs say val is "interpreted as unsigned char".
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
let val = val as u8;
|
||||
@ -664,7 +664,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
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_scalar(num)?.to_machine_usize(this)?;
|
||||
let num = this.read_machine_usize(num)?;
|
||||
// The docs say val is "interpreted as unsigned char".
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
let val = val as u8;
|
||||
|
@ -111,7 +111,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let ty_layout = this.layout_of(ty)?;
|
||||
let val_byte = this.read_scalar(val_byte)?.to_u8()?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let count = this.read_scalar(count)?.to_machine_usize(this)?;
|
||||
let count = this.read_machine_usize(count)?;
|
||||
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
|
||||
// but no actual allocation can be big enough for the difference to be noticeable.
|
||||
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
|
||||
@ -124,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [ptr, mask] = check_arg_count(args)?;
|
||||
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let mask = this.read_scalar(mask)?.to_machine_usize(this)?;
|
||||
let mask = this.read_machine_usize(mask)?;
|
||||
|
||||
let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask);
|
||||
|
||||
|
@ -80,7 +80,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let req_align = this.read_scalar(align_op)?.to_machine_usize(this)?;
|
||||
let req_align = this.read_machine_usize(align_op)?;
|
||||
|
||||
// Stop if the alignment is not a power of two.
|
||||
if !req_align.is_power_of_two() {
|
||||
|
@ -78,7 +78,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [fd, buf, count] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let fd = this.read_scalar(fd)?.to_i32()?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let count = this.read_scalar(count)?.to_machine_usize(this)?;
|
||||
let count = this.read_machine_usize(count)?;
|
||||
let result = this.read(fd, buf, count)?;
|
||||
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
|
||||
}
|
||||
@ -86,7 +86,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [fd, buf, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let fd = this.read_scalar(fd)?.to_i32()?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let count = this.read_scalar(n)?.to_machine_usize(this)?;
|
||||
let count = this.read_machine_usize(n)?;
|
||||
trace!("Called write({:?}, {:?}, {:?})", fd, buf, count);
|
||||
let result = this.write(fd, buf, count)?;
|
||||
// Now, `result` is the value we return back to the program.
|
||||
@ -157,8 +157,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [fd, offset, len, advice] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(fd)?.to_i32()?;
|
||||
this.read_scalar(offset)?.to_machine_isize(this)?;
|
||||
this.read_scalar(len)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(offset)?;
|
||||
this.read_machine_isize(len)?;
|
||||
this.read_scalar(advice)?.to_i32()?;
|
||||
// fadvise is only informational, we can ignore it.
|
||||
this.write_null(dest)?;
|
||||
@ -191,8 +191,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"posix_memalign" => {
|
||||
let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ret = this.deref_operand(ret)?;
|
||||
let align = this.read_scalar(align)?.to_machine_usize(this)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
// Align must be power of 2, and also at least ptr-sized (POSIX rules).
|
||||
// But failure to adhere to this is not UB, it's an error condition.
|
||||
if !align.is_power_of_two() || align < this.pointer_size().bytes() {
|
||||
@ -216,7 +216,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// Dynamic symbol loading
|
||||
"dlsym" => {
|
||||
let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(handle)?.to_machine_usize(this)?;
|
||||
this.read_machine_usize(handle)?;
|
||||
let symbol = this.read_pointer(symbol)?;
|
||||
let symbol_name = this.read_c_str(symbol)?;
|
||||
if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)? {
|
||||
@ -472,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [errnum, buf, buflen] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let errnum = this.read_scalar(errnum)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let buflen = this.read_scalar(buflen)?.to_machine_usize(this)?;
|
||||
let buflen = this.read_machine_usize(buflen)?;
|
||||
|
||||
let error = this.try_errnum_to_io_error(errnum)?;
|
||||
let formatted = match error {
|
||||
@ -565,7 +565,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let uid = this.read_scalar(uid)?.to_u32()?;
|
||||
let pwd = this.deref_operand(pwd)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let buflen = this.read_scalar(buflen)?.to_machine_usize(this)?;
|
||||
let buflen = this.read_machine_usize(buflen)?;
|
||||
let result = this.deref_operand(result)?;
|
||||
|
||||
// Must be for "us".
|
||||
|
@ -1293,7 +1293,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
this.assert_target_os("linux", "readdir64");
|
||||
|
||||
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
|
||||
let dirp = this.read_machine_usize(dirp_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
@ -1385,7 +1385,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
this.assert_target_os("macos", "readdir_r");
|
||||
|
||||
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
|
||||
let dirp = this.read_machine_usize(dirp_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
@ -1478,7 +1478,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn closedir(&mut self, dirp_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
|
||||
let dirp = this.read_machine_usize(dirp_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
@ -1642,7 +1642,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
let pathname = this.read_path_from_c_str(this.read_pointer(pathname_op)?)?;
|
||||
let buf = this.read_pointer(buf_op)?;
|
||||
let bufsize = this.read_scalar(bufsize_op)?.to_machine_usize(this)?;
|
||||
let bufsize = this.read_machine_usize(bufsize_op)?;
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
|
||||
|
@ -99,7 +99,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"incorrect number of arguments for syscall: got 0, expected at least 1"
|
||||
);
|
||||
}
|
||||
match this.read_scalar(&args[0])?.to_machine_usize(this)? {
|
||||
match this.read_machine_usize(&args[0])? {
|
||||
// `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
|
||||
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
|
||||
id if id == sys_getrandom => {
|
||||
@ -147,7 +147,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [pid, cpusetsize, mask] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(pid)?.to_i32()?;
|
||||
this.read_scalar(cpusetsize)?.to_machine_usize(this)?;
|
||||
this.read_machine_usize(cpusetsize)?;
|
||||
this.deref_operand(mask)?;
|
||||
// FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
|
||||
let einval = this.eval_libc("EINVAL")?;
|
||||
@ -179,7 +179,7 @@ fn getrandom<'tcx>(
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_scalar(len)?.to_machine_usize(this)?;
|
||||
let len = this.read_machine_usize(len)?;
|
||||
|
||||
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
|
||||
// neither of which have any effect on our current PRNG.
|
||||
|
@ -39,7 +39,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
Dlsym::getentropy => {
|
||||
let [ptr, len] = check_arg_count(args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_scalar(len)?.to_machine_usize(this)?;
|
||||
let len = this.read_machine_usize(len)?;
|
||||
this.gen_random(ptr, len)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
@ -161,13 +161,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// Querying system information
|
||||
"pthread_get_stackaddr_np" => {
|
||||
let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(thread)?.to_machine_usize(this)?;
|
||||
this.read_machine_usize(thread)?;
|
||||
let stack_addr = Scalar::from_uint(STACK_ADDR, this.pointer_size());
|
||||
this.write_scalar(stack_addr, dest)?;
|
||||
}
|
||||
"pthread_get_stacksize_np" => {
|
||||
let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(thread)?.to_machine_usize(this)?;
|
||||
this.read_machine_usize(thread)?;
|
||||
let stack_size = Scalar::from_uint(STACK_SIZE, this.pointer_size());
|
||||
this.write_scalar(stack_size, dest)?;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
|
||||
}
|
||||
|
||||
let thread_id = this.read_scalar(thread)?.to_machine_usize(this)?;
|
||||
let thread_id = this.read_machine_usize(thread)?;
|
||||
this.join_thread_exclusive(thread_id.try_into().expect("thread ID should fit in u32"))?;
|
||||
|
||||
Ok(0)
|
||||
@ -51,7 +51,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn pthread_detach(&mut self, thread: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread_id = this.read_scalar(thread)?.to_machine_usize(this)?;
|
||||
let thread_id = this.read_machine_usize(thread)?;
|
||||
this.detach_thread(
|
||||
thread_id.try_into().expect("thread ID should fit in u32"),
|
||||
/*allow_terminated_joined*/ false,
|
||||
|
@ -67,10 +67,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
byte_offset,
|
||||
_key,
|
||||
] = check_arg_count(args)?;
|
||||
let handle = this.read_scalar(handle)?.to_machine_isize(this)?;
|
||||
let handle = this.read_machine_isize(handle)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let n = this.read_scalar(n)?.to_u32()?;
|
||||
let byte_offset = this.read_scalar(byte_offset)?.to_machine_usize(this)?; // is actually a pointer
|
||||
let byte_offset = this.read_machine_usize(byte_offset)?; // is actually a pointer
|
||||
let io_status_block = this.deref_operand(io_status_block)?;
|
||||
|
||||
if byte_offset != 0 {
|
||||
|
@ -73,9 +73,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"HeapAlloc" => {
|
||||
let [handle, flags, size] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(handle)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(handle)?;
|
||||
let flags = this.read_scalar(flags)?.to_u32()?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
|
||||
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
@ -83,7 +83,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"HeapFree" => {
|
||||
let [handle, flags, ptr] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(handle)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(handle)?;
|
||||
this.read_scalar(flags)?.to_u32()?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
this.free(ptr, MiriMemoryKind::WinHeap)?;
|
||||
@ -92,10 +92,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"HeapReAlloc" => {
|
||||
let [handle, flags, ptr, size] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(handle)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(handle)?;
|
||||
this.read_scalar(flags)?.to_u32()?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let size = this.read_scalar(size)?.to_machine_usize(this)?;
|
||||
let size = this.read_machine_usize(size)?;
|
||||
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
@ -298,7 +298,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
let [hModule, lpProcName] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(hModule)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(hModule)?;
|
||||
let name = this.read_c_str(this.read_pointer(lpProcName)?)?;
|
||||
if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.os)? {
|
||||
let ptr = this.create_fn_alloc_ptr(FnVal::Other(dlsym));
|
||||
@ -356,7 +356,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// `term` needs this, so we fake it.
|
||||
let [console, buffer_info] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(console)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(console)?;
|
||||
this.deref_operand(buffer_info)?;
|
||||
// Indicate an error.
|
||||
// FIXME: we should set last_error, but to what?
|
||||
@ -432,7 +432,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"GetConsoleMode" if this.frame_in_std() => {
|
||||
let [console, mode] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_scalar(console)?.to_machine_isize(this)?;
|
||||
this.read_machine_isize(console)?;
|
||||
this.deref_operand(mode)?;
|
||||
// Indicate an error.
|
||||
this.write_null(dest)?;
|
||||
|
@ -273,7 +273,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
let ptr = this.read_pointer(ptr_op)?;
|
||||
let compare = this.read_pointer(compare_op)?;
|
||||
let size = this.read_scalar(size_op)?.to_machine_usize(this)?;
|
||||
let size = this.read_machine_usize(size_op)?;
|
||||
let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?;
|
||||
|
||||
let thread = this.get_active_thread();
|
||||
|
@ -21,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
let security = this.read_pointer(security_op)?;
|
||||
// stacksize is ignored, but still needs to be a valid usize
|
||||
this.read_scalar(stacksize_op)?.to_machine_usize(this)?;
|
||||
this.read_machine_usize(stacksize_op)?;
|
||||
let start_routine = this.read_pointer(start_op)?;
|
||||
let func_arg = this.read_immediate(arg_op)?;
|
||||
let flags = this.read_scalar(flags_op)?.to_u32()?;
|
||||
|
@ -7,7 +7,7 @@ struct Data {
|
||||
ptr: &'static i32,
|
||||
}
|
||||
|
||||
// But we need to gurantee some alignment
|
||||
// But we need to guarantee some alignment
|
||||
struct Wrapper {
|
||||
align: u64,
|
||||
data: Data,
|
||||
|
Loading…
Reference in New Issue
Block a user