Auto merge of #2422 - RalfJung:integers, r=oli-obk
enable clippy lints against integer casts Cc https://github.com/rust-lang/miri/issues/1236
This commit is contained in:
commit
6227e1e3a8
@ -230,6 +230,7 @@ pub fn abs_ptr_to_rel(
|
|||||||
|
|
||||||
// Wrapping "addr - base_addr"
|
// Wrapping "addr - base_addr"
|
||||||
let dl = ecx.data_layout();
|
let dl = ecx.data_layout();
|
||||||
|
#[allow(clippy::cast_possible_wrap)] // we want to wrap here
|
||||||
let neg_base_addr = (base_addr as i64).wrapping_neg();
|
let neg_base_addr = (base_addr as i64).wrapping_neg();
|
||||||
Some((
|
Some((
|
||||||
alloc_id,
|
alloc_id,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#![feature(is_some_with)]
|
#![feature(is_some_with)]
|
||||||
#![feature(nonzero_ops)]
|
#![feature(nonzero_ops)]
|
||||||
#![feature(local_key_cell_methods)]
|
#![feature(local_key_cell_methods)]
|
||||||
#![warn(rust_2018_idioms)]
|
// Configure clippy and other lints
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::collapsible_else_if,
|
clippy::collapsible_else_if,
|
||||||
clippy::collapsible_if,
|
clippy::collapsible_if,
|
||||||
@ -24,6 +24,13 @@
|
|||||||
clippy::derive_hash_xor_eq,
|
clippy::derive_hash_xor_eq,
|
||||||
clippy::too_many_arguments
|
clippy::too_many_arguments
|
||||||
)]
|
)]
|
||||||
|
#![warn(
|
||||||
|
rust_2018_idioms,
|
||||||
|
clippy::cast_possible_wrap, // unsigned -> signed
|
||||||
|
clippy::cast_sign_loss, // signed -> unsigned
|
||||||
|
clippy::cast_lossless,
|
||||||
|
clippy::cast_possible_truncation,
|
||||||
|
)]
|
||||||
|
|
||||||
extern crate rustc_apfloat;
|
extern crate rustc_apfloat;
|
||||||
extern crate rustc_ast;
|
extern crate rustc_ast;
|
||||||
|
@ -171,9 +171,11 @@ fn handle_miri_resolve_frame(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let lineno: u32 = lo.line as u32;
|
// `u32` is not enough to fit line/colno, which can be `usize`. It seems unlikely that a
|
||||||
|
// file would have more than 2^32 lines or columns, but whatever, just default to 0.
|
||||||
|
let lineno: u32 = u32::try_from(lo.line).unwrap_or(0);
|
||||||
// `lo.col` is 0-based - add 1 to make it 1-based for the caller.
|
// `lo.col` is 0-based - add 1 to make it 1-based for the caller.
|
||||||
let colno: u32 = lo.col.0 as u32 + 1;
|
let colno: u32 = u32::try_from(lo.col.0 + 1).unwrap_or(0);
|
||||||
|
|
||||||
let dest = this.force_allocation(dest)?;
|
let dest = this.force_allocation(dest)?;
|
||||||
if let ty::Adt(adt, _) = dest.layout.ty.kind() {
|
if let ty::Adt(adt, _) = dest.layout.ty.kind() {
|
||||||
|
@ -202,7 +202,7 @@ fn FreeEnvironmentStringsW(
|
|||||||
let env_block_ptr = this.read_pointer(env_block_op)?;
|
let env_block_ptr = this.read_pointer(env_block_op)?;
|
||||||
let result = this.deallocate_ptr(env_block_ptr, None, MiriMemoryKind::Runtime.into());
|
let result = this.deallocate_ptr(env_block_ptr, None, MiriMemoryKind::Runtime.into());
|
||||||
// If the function succeeds, the return value is nonzero.
|
// If the function succeeds, the return value is nonzero.
|
||||||
Ok(result.is_ok() as i32)
|
Ok(i32::from(result.is_ok()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setenv(
|
fn setenv(
|
||||||
@ -459,7 +459,7 @@ fn getpid(&mut self) -> InterpResult<'tcx, i32> {
|
|||||||
// The reason we need to do this wacky of a conversion is because
|
// The reason we need to do this wacky of a conversion is because
|
||||||
// `libc::getpid` returns an i32, however, `std::process::id()` return an u32.
|
// `libc::getpid` returns an i32, however, `std::process::id()` return an u32.
|
||||||
// So we un-do the conversion that stdlib does and turn it back into an i32.
|
// So we un-do the conversion that stdlib does and turn it back into an i32.
|
||||||
|
#[allow(clippy::cast_possible_wrap)]
|
||||||
Ok(std::process::id() as i32)
|
Ok(std::process::id() as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +82,12 @@ fn malloc(
|
|||||||
let align = this.min_align(size, kind);
|
let align = this.min_align(size, kind);
|
||||||
let ptr = this.allocate_ptr(Size::from_bytes(size), align, kind.into())?;
|
let ptr = this.allocate_ptr(Size::from_bytes(size), align, kind.into())?;
|
||||||
if zero_init {
|
if zero_init {
|
||||||
// We just allocated this, the access is definitely in-bounds.
|
// We just allocated this, the access is definitely in-bounds and fits into our address space.
|
||||||
this.write_bytes_ptr(ptr.into(), iter::repeat(0u8).take(size as usize)).unwrap();
|
this.write_bytes_ptr(
|
||||||
|
ptr.into(),
|
||||||
|
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
Ok(ptr.into())
|
Ok(ptr.into())
|
||||||
}
|
}
|
||||||
@ -526,8 +530,12 @@ fn emulate_foreign_item_by_name(
|
|||||||
"memrchr" => {
|
"memrchr" => {
|
||||||
let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let ptr = this.read_pointer(ptr)?;
|
let ptr = this.read_pointer(ptr)?;
|
||||||
let val = this.read_scalar(val)?.to_i32()? as u8;
|
let val = this.read_scalar(val)?.to_i32()?;
|
||||||
let num = this.read_scalar(num)?.to_machine_usize(this)?;
|
let num = this.read_scalar(num)?.to_machine_usize(this)?;
|
||||||
|
// The docs say val is "interpreted as unsigned char".
|
||||||
|
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
|
let val = val as u8;
|
||||||
|
|
||||||
if let Some(idx) = this
|
if let Some(idx) = this
|
||||||
.read_bytes_ptr(ptr, Size::from_bytes(num))?
|
.read_bytes_ptr(ptr, Size::from_bytes(num))?
|
||||||
.iter()
|
.iter()
|
||||||
@ -543,8 +551,12 @@ fn emulate_foreign_item_by_name(
|
|||||||
"memchr" => {
|
"memchr" => {
|
||||||
let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let ptr = this.read_pointer(ptr)?;
|
let ptr = this.read_pointer(ptr)?;
|
||||||
let val = this.read_scalar(val)?.to_i32()? as u8;
|
let val = this.read_scalar(val)?.to_i32()?;
|
||||||
let num = this.read_scalar(num)?.to_machine_usize(this)?;
|
let num = this.read_scalar(num)?.to_machine_usize(this)?;
|
||||||
|
// The docs say val is "interpreted as unsigned char".
|
||||||
|
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
|
let val = val as u8;
|
||||||
|
|
||||||
let idx = this
|
let idx = this
|
||||||
.read_bytes_ptr(ptr, Size::from_bytes(num))?
|
.read_bytes_ptr(ptr, Size::from_bytes(num))?
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -117,10 +117,7 @@ fn emulate_intrinsic_by_name(
|
|||||||
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
|
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
|
||||||
err_ub_format!("overflow computing total size of `{intrinsic_name}`")
|
err_ub_format!("overflow computing total size of `{intrinsic_name}`")
|
||||||
})?;
|
})?;
|
||||||
this.write_bytes_ptr(
|
this.write_bytes_ptr(ptr, iter::repeat(val_byte).take(byte_count.bytes_usize()))?;
|
||||||
ptr,
|
|
||||||
iter::repeat(val_byte).take(byte_count.bytes() as usize),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Floating-point operations
|
// Floating-point operations
|
||||||
|
@ -73,7 +73,7 @@ pub fn create_tls_key(
|
|||||||
self.keys.try_insert(new_key, TlsEntry { data: Default::default(), dtor }).unwrap();
|
self.keys.try_insert(new_key, TlsEntry { data: Default::default(), dtor }).unwrap();
|
||||||
trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
|
trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
|
||||||
|
|
||||||
if max_size.bits() < 128 && new_key >= (1u128 << max_size.bits() as u128) {
|
if max_size.bits() < 128 && new_key >= (1u128 << max_size.bits()) {
|
||||||
throw_unsup_format!("we ran out of TLS key space");
|
throw_unsup_format!("we ran out of TLS key space");
|
||||||
}
|
}
|
||||||
Ok(new_key)
|
Ok(new_key)
|
||||||
|
@ -776,15 +776,17 @@ fn read(
|
|||||||
|
|
||||||
// We cap the number of read bytes to the largest value that we are able to fit in both the
|
// We cap the number of read bytes to the largest value that we are able to fit in both the
|
||||||
// host's and target's `isize`. This saves us from having to handle overflows later.
|
// host's and target's `isize`. This saves us from having to handle overflows later.
|
||||||
let count = count.min(this.machine_isize_max() as u64).min(isize::MAX as u64);
|
let count = count
|
||||||
|
.min(u64::try_from(this.machine_isize_max()).unwrap())
|
||||||
|
.min(u64::try_from(isize::MAX).unwrap());
|
||||||
let communicate = this.machine.communicate();
|
let communicate = this.machine.communicate();
|
||||||
|
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get_mut(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get_mut(&fd) {
|
||||||
trace!("read: FD mapped to {:?}", file_descriptor);
|
trace!("read: FD mapped to {:?}", file_descriptor);
|
||||||
// We want to read at most `count` bytes. We are sure that `count` is not negative
|
// We want to read at most `count` bytes. We are sure that `count` is not negative
|
||||||
// because it was a target's `usize`. Also we are sure that its smaller than
|
// because it was a target's `usize`. Also we are sure that its smaller than
|
||||||
// `usize::MAX` because it is a host's `isize`.
|
// `usize::MAX` because it is bounded by the host's `isize`.
|
||||||
let mut bytes = vec![0; count as usize];
|
let mut bytes = vec![0; usize::try_from(count).unwrap()];
|
||||||
// `File::read` never returns a value larger than `count`,
|
// `File::read` never returns a value larger than `count`,
|
||||||
// so this cannot fail.
|
// so this cannot fail.
|
||||||
let result =
|
let result =
|
||||||
@ -827,7 +829,9 @@ fn write(
|
|||||||
|
|
||||||
// We cap the number of written bytes to the largest value that we are able to fit in both the
|
// We cap the number of written bytes to the largest value that we are able to fit in both the
|
||||||
// host's and target's `isize`. This saves us from having to handle overflows later.
|
// host's and target's `isize`. This saves us from having to handle overflows later.
|
||||||
let count = count.min(this.machine_isize_max() as u64).min(isize::MAX as u64);
|
let count = count
|
||||||
|
.min(u64::try_from(this.machine_isize_max()).unwrap())
|
||||||
|
.min(u64::try_from(isize::MAX).unwrap());
|
||||||
let communicate = this.machine.communicate();
|
let communicate = this.machine.communicate();
|
||||||
|
|
||||||
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
|
||||||
|
@ -84,7 +84,8 @@ fn call_dlsym(
|
|||||||
} else {
|
} else {
|
||||||
io::stderr().write(buf_cont)
|
io::stderr().write(buf_cont)
|
||||||
};
|
};
|
||||||
res.ok().map(|n| n as u32)
|
// We write at most `n` bytes, which is a `u32`, so we cannot have written more than that.
|
||||||
|
res.ok().map(|n| u32::try_from(n).unwrap())
|
||||||
} else {
|
} else {
|
||||||
throw_unsup_format!(
|
throw_unsup_format!(
|
||||||
"on Windows, writing to anything except stdout/stderr is not supported"
|
"on Windows, writing to anything except stdout/stderr is not supported"
|
||||||
@ -102,7 +103,7 @@ fn call_dlsym(
|
|||||||
// Return whether this was a success. >= 0 is success.
|
// Return whether this was a success. >= 0 is success.
|
||||||
// For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
|
// For the error code we arbitrarily pick 0xC0000185, STATUS_IO_DEVICE_ERROR.
|
||||||
this.write_scalar(
|
this.write_scalar(
|
||||||
Scalar::from_i32(if written.is_some() { 0 } else { 0xC0000185u32 as i32 }),
|
Scalar::from_u32(if written.is_some() { 0 } else { 0xC0000185u32 }),
|
||||||
dest,
|
dest,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ fn emulate_foreign_item_by_name(
|
|||||||
// Initialize with `0`.
|
// Initialize with `0`.
|
||||||
this.write_bytes_ptr(
|
this.write_bytes_ptr(
|
||||||
system_info.ptr,
|
system_info.ptr,
|
||||||
iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
|
iter::repeat(0u8).take(system_info.layout.size.bytes_usize()),
|
||||||
)?;
|
)?;
|
||||||
// Set selected fields.
|
// Set selected fields.
|
||||||
let word_layout = this.machine.layouts.u16;
|
let word_layout = this.machine.layouts.u16;
|
||||||
|
@ -22,7 +22,7 @@ pub fn new(tag: SbTag, perm: Permission, protected: bool) -> Self {
|
|||||||
assert!(tag.0.get() <= TAG_MASK);
|
assert!(tag.0.get() <= TAG_MASK);
|
||||||
let packed_tag = tag.0.get();
|
let packed_tag = tag.0.get();
|
||||||
let packed_perm = perm.to_bits() << PERM_SHIFT;
|
let packed_perm = perm.to_bits() << PERM_SHIFT;
|
||||||
let packed_protected = (protected as u64) << PROTECTED_SHIFT;
|
let packed_protected = u64::from(protected) << PROTECTED_SHIFT;
|
||||||
|
|
||||||
let new = Self(packed_tag | packed_perm | packed_protected);
|
let new = Self(packed_tag | packed_perm | packed_protected);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user