From f0298aca574fc2e64d6e1d6747a6ff4c8c3ab52b Mon Sep 17 00:00:00 2001 From: David Roundy Date: Fri, 16 Sep 2022 05:46:19 -0700 Subject: [PATCH] maybe fix miri complaint (thanks @semicoleon!) --- src/setu32.rs | 23 ++++++++++++++++++++--- src/setu64.rs | 22 ++++++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/setu32.rs b/src/setu32.rs index e20fcaa..a00979f 100644 --- a/src/setu32.rs +++ b/src/setu32.rs @@ -1523,7 +1523,16 @@ impl SetU32 { } else { let s = unsafe { &*self.0 }; let b = &s.b; - let a = unsafe { std::slice::from_raw_parts(&s.array as *const u32, b.cap as usize) }; + let array = unsafe { + // Use the calculated offset to jump the pointer to where the array starts directly, keeping the permissions for the whole allocation intact. + self.0.cast::().offset( + // get a raw pointer to the array field + (&s.array as *const u32) + // calculate the offset from `*mut S` to the array field + .offset_from(self.0.cast()), + ) + }; + let a = unsafe { std::slice::from_raw_parts(array, b.cap as usize) }; if b.bits == 0 || b.bits > 32 { Internal::Big { s: b, a } } else if b.bits == 32 { @@ -1542,8 +1551,16 @@ impl SetU32 { } else { let s = unsafe { &mut *self.0 }; let b = &mut s.b; - let a = - unsafe { std::slice::from_raw_parts_mut(&mut s.array as *mut u32, b.cap as usize) }; + let array = unsafe { + // Use the calculated offset to jump the pointer to where the array starts directly, keeping the permissions for the whole allocation intact. + self.0.cast::().offset( + // get a raw pointer to the array field + (&mut s.array as *mut u32) + // calculate the offset from `*mut S` to the array field + .offset_from(self.0.cast()), + ) + }; + let a = unsafe { std::slice::from_raw_parts_mut(array, b.cap as usize) }; if b.bits == 0 || b.bits > 32 { InternalMut::Big { s: b, a } } else if b.bits == 32 { diff --git a/src/setu64.rs b/src/setu64.rs index 7b22852..6d22b3a 100644 --- a/src/setu64.rs +++ b/src/setu64.rs @@ -1254,7 +1254,16 @@ impl SetU64 { } else { let s = unsafe { &*self.0 }; let b = &s.b; - let a = unsafe { std::slice::from_raw_parts(&s.array as *const u64, b.cap) }; + let array = unsafe { + // Use the calculated offset to jump the pointer to where the array starts directly, keeping the permissions for the whole allocation intact. + self.0.cast::().offset( + // get a raw pointer to the array field + (&s.array as *const u64) + // calculate the offset from `*mut S` to the array field + .offset_from(self.0.cast()), + ) + }; + let a = unsafe { std::slice::from_raw_parts(array, b.cap as usize) }; if b.bits == 0 || b.bits > 64 { Internal::Big { s: b, a } } else if b.bits == 64 { @@ -1273,7 +1282,16 @@ impl SetU64 { } else { let s = unsafe { &mut *self.0 }; let b = &mut s.b; - let a = unsafe { std::slice::from_raw_parts_mut(&mut s.array as *mut u64, b.cap) }; + let array = unsafe { + // Use the calculated offset to jump the pointer to where the array starts directly, keeping the permissions for the whole allocation intact. + self.0.cast::().offset( + // get a raw pointer to the array field + (&mut s.array as *mut u64) + // calculate the offset from `*mut S` to the array field + .offset_from(self.0.cast()), + ) + }; + let a = unsafe { std::slice::from_raw_parts_mut(array, b.cap as usize) }; if b.bits == 0 || b.bits > 64 { InternalMut::Big { s: b, a } } else if b.bits == 64 {