diff --git a/src/lib.rs b/src/lib.rs index 8ca3e8d15e1..aff63c3c19d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ clippy::too_many_arguments, clippy::type_complexity, clippy::single_element_loop, + clippy::needless_return, // We are not implementing queries here so it's fine rustc::potential_query_instability )] diff --git a/src/shims/backtrace.rs b/src/shims/backtrace.rs index 9182b2a7217..bce4961339c 100644 --- a/src/shims/backtrace.rs +++ b/src/shims/backtrace.rs @@ -175,7 +175,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // 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. - let colno: u32 = u32::try_from(lo.col.0 + 1).unwrap_or(0); + let colno: u32 = u32::try_from(lo.col.0.saturating_add(1)).unwrap_or(0); let dest = this.force_allocation(dest)?; if let ty::Adt(adt, _) = dest.layout.ty.kind() { diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index e7cfd43f1b1..b9bd713d4d3 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -164,6 +164,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx .expect("interpreting a non-executable crate"); for cnum in iter::once(LOCAL_CRATE).chain( dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| { + // We add 1 to the number because that's what rustc also does everywhere it + // calls `CrateNum::new`... + #[allow(clippy::integer_arithmetic)] (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)) }), ) { @@ -542,7 +545,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx .rev() .position(|&c| c == val) { - let new_ptr = ptr.offset(Size::from_bytes(num - idx as u64 - 1), this)?; + let idx = u64::try_from(idx).unwrap(); + #[allow(clippy::integer_arithmetic)] // idx < num, so this never wraps + let new_ptr = ptr.offset(Size::from_bytes(num - idx - 1), this)?; this.write_pointer(new_ptr, dest)?; } else { this.write_null(dest)?; @@ -708,7 +713,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let a = this.read_scalar(a)?.to_u64()?; let b = this.read_scalar(b)?.to_u64()?; + #[allow(clippy::integer_arithmetic)] // adding two u64 and a u8 cannot wrap in a u128 let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b); + #[allow(clippy::integer_arithmetic)] // it's a u128, we can shift by 64 let (c_out, sum) = ((wide_sum >> 64).truncate::(), wide_sum.truncate::()); let c_out_field = this.place_field(dest, 0)?; diff --git a/src/shims/intrinsics/simd.rs b/src/shims/intrinsics/simd.rs index 0c3241683a1..1b7ec591350 100644 --- a/src/shims/intrinsics/simd.rs +++ b/src/shims/intrinsics/simd.rs @@ -393,6 +393,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx assert_eq!(bitmask_len, mask.layout.size.bits()); assert_eq!(dest_len, yes_len); assert_eq!(dest_len, no_len); + let dest_len = u32::try_from(dest_len).unwrap(); + let bitmask_len = u32::try_from(bitmask_len).unwrap(); let mask: u64 = this .read_scalar(mask)? @@ -401,18 +403,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx .try_into() .unwrap(); for i in 0..dest_len { - let mask = - mask & (1 << simd_bitmask_index(i, dest_len, this.data_layout().endian)); - let yes = this.read_immediate(&this.mplace_index(&yes, i)?.into())?; - let no = this.read_immediate(&this.mplace_index(&no, i)?.into())?; - let dest = this.mplace_index(&dest, i)?; + let mask = mask + & 1u64 + .checked_shl(simd_bitmask_index(i, dest_len, this.data_layout().endian)) + .unwrap(); + let yes = this.read_immediate(&this.mplace_index(&yes, i.into())?.into())?; + let no = this.read_immediate(&this.mplace_index(&no, i.into())?.into())?; + let dest = this.mplace_index(&dest, i.into())?; let val = if mask != 0 { yes } else { no }; this.write_immediate(*val, &dest.into())?; } for i in dest_len..bitmask_len { // If the mask is "padded", ensure that padding is all-zero. - let mask = mask & (1 << i); + let mask = mask & 1u64.checked_shl(i).unwrap(); if mask != 0 { throw_ub_format!( "a SIMD bitmask less than 8 bits long must be filled with 0s for the remaining bits" @@ -485,9 +489,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let val = if src_index < left_len { this.read_immediate(&this.mplace_index(&left, src_index)?.into())? } else if src_index < left_len.checked_add(right_len).unwrap() { - this.read_immediate( - &this.mplace_index(&right, src_index - left_len)?.into(), - )? + let right_idx = src_index.checked_sub(left_len).unwrap(); + this.read_immediate(&this.mplace_index(&right, right_idx)?.into())? } else { span_bug!( this.cur_span(), @@ -551,12 +554,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx assert!(dest.layout.ty.is_integral()); assert!(bitmask_len <= 64); assert_eq!(bitmask_len, dest.layout.size.bits()); + let op_len = u32::try_from(op_len).unwrap(); let mut res = 0u64; for i in 0..op_len { - let op = this.read_immediate(&this.mplace_index(&op, i)?.into())?; + let op = this.read_immediate(&this.mplace_index(&op, i.into())?.into())?; if simd_element_to_bool(op)? { - res |= 1 << simd_bitmask_index(i, op_len, this.data_layout().endian); + res |= 1u64 + .checked_shl(simd_bitmask_index(i, op_len, this.data_layout().endian)) + .unwrap(); } } this.write_int(res, dest)?; @@ -583,10 +589,11 @@ fn simd_element_to_bool(elem: ImmTy<'_, Provenance>) -> InterpResult<'_, bool> { }) } -fn simd_bitmask_index(idx: u64, vec_len: u64, endianess: Endian) -> u64 { +fn simd_bitmask_index(idx: u32, vec_len: u32, endianess: Endian) -> u32 { assert!(idx < vec_len); match endianess { Endian::Little => idx, + #[allow(clippy::integer_arithmetic)] // idx < vec_len Endian::Big => vec_len - 1 - idx, // reverse order of bits } } diff --git a/src/shims/mod.rs b/src/shims/mod.rs index f5b4de30a57..61829559245 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -1,3 +1,5 @@ +#![warn(clippy::integer_arithmetic)] + mod backtrace; pub mod foreign_items; pub mod intrinsics; diff --git a/src/shims/time.rs b/src/shims/time.rs index 67303c47db7..d3c545ea58c 100644 --- a/src/shims/time.rs +++ b/src/shims/time.rs @@ -84,7 +84,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx Ok(0) } - #[allow(non_snake_case)] + #[allow(non_snake_case, clippy::integer_arithmetic)] fn GetSystemTimeAsFileTime( &mut self, LPFILETIME_op: &OpTy<'tcx, Provenance>, diff --git a/src/shims/tls.rs b/src/shims/tls.rs index a5205487981..ede4b12c2d2 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -63,6 +63,7 @@ impl<'tcx> Default for TlsData<'tcx> { impl<'tcx> TlsData<'tcx> { /// Generate a new TLS key with the given destructor. /// `max_size` determines the integer size the key has to fit in. + #[allow(clippy::integer_arithmetic)] pub fn create_tls_key( &mut self, dtor: Option>, diff --git a/src/shims/unix/fs.rs b/src/shims/unix/fs.rs index 2a6499ce999..d3f4f5ef545 100644 --- a/src/shims/unix/fs.rs +++ b/src/shims/unix/fs.rs @@ -443,6 +443,7 @@ pub struct DirHandler { } impl DirHandler { + #[allow(clippy::integer_arithmetic)] fn insert_new(&mut self, read_dir: ReadDir) -> u64 { let id = self.next_id; self.next_id += 1; diff --git a/src/shims/unix/linux/sync.rs b/src/shims/unix/linux/sync.rs index b33553f4663..f9c97a23721 100644 --- a/src/shims/unix/linux/sync.rs +++ b/src/shims/unix/linux/sync.rs @@ -242,6 +242,7 @@ pub fn futex<'tcx>( // before doing the syscall. this.atomic_fence(AtomicFenceOrd::SeqCst)?; let mut n = 0; + #[allow(clippy::integer_arithmetic)] for _ in 0..val { if let Some(thread) = this.futex_wake(addr_usize, bitset) { this.unblock_thread(thread); diff --git a/src/shims/windows/handle.rs b/src/shims/windows/handle.rs index 443af1dfeaa..92e0a9a34e1 100644 --- a/src/shims/windows/handle.rs +++ b/src/shims/windows/handle.rs @@ -62,6 +62,7 @@ impl Handle { let floor_log2 = variant_count.ilog2(); // we need to add one for non powers of two to compensate for the difference + #[allow(clippy::integer_arithmetic)] // cannot overflow if variant_count.is_power_of_two() { floor_log2 } else { floor_log2 + 1 } } @@ -73,7 +74,7 @@ impl Handle { /// None of this layout is guaranteed to applications by Windows or Miri. fn to_packed(self) -> u32 { let disc_size = Self::packed_disc_size(); - let data_size = u32::BITS - disc_size; + let data_size = u32::BITS.checked_sub(disc_size).unwrap(); let discriminant = self.discriminant(); let data = self.data(); @@ -86,7 +87,8 @@ impl Handle { // packs the data into the lower `data_size` bits // and packs the discriminant right above the data - discriminant << data_size | data + #[allow(clippy::integer_arithmetic)] // cannot overflow + return discriminant << data_size | data; } fn new(discriminant: u32, data: u32) -> Option { @@ -101,12 +103,14 @@ impl Handle { /// see docs for `to_packed` fn from_packed(handle: u32) -> Option { let disc_size = Self::packed_disc_size(); - let data_size = u32::BITS - disc_size; + let data_size = u32::BITS.checked_sub(disc_size).unwrap(); // the lower `data_size` bits of this mask are 1 + #[allow(clippy::integer_arithmetic)] // cannot overflow let data_mask = 2u32.pow(data_size) - 1; // the discriminant is stored right above the lower `data_size` bits + #[allow(clippy::integer_arithmetic)] // cannot overflow let discriminant = handle >> data_size; // the data is stored in the lower `data_size` bits