Skip to content

Commit 6385d4a

Browse files
authored
Merge pull request #12 from stogaru/verify/ptr_mut_refactor_harness
Verify/ptr mut refactor harness
2 parents 46e839c + cb6a177 commit 6385d4a

File tree

1 file changed

+139
-89
lines changed

1 file changed

+139
-89
lines changed

library/core/src/ptr/mut_ptr.rs

Lines changed: 139 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -407,10 +407,20 @@ impl<T: ?Sized> *mut T {
407407
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
408408
#[inline(always)]
409409
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
410-
#[requires(kani::mem::can_dereference(self))]
411-
// TODO: Determine the valid value range for 'count' and update the precondition accordingly.
412-
#[requires(count == 0)] // This precondition is currently a placeholder.
413-
#[ensures(|result| kani::mem::can_dereference(result))]
410+
#[requires(
411+
// Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`
412+
count.checked_mul(core::mem::size_of::<T>() as isize).is_some() &&
413+
// Precondition 2: adding the computed offset to `self` does not cause overflow
414+
(self as isize).checked_add((count * core::mem::size_of::<T>() as isize)).is_some() &&
415+
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
416+
// Otherwise, for non-unit types, `self` and `self.wrapping_offset(count)` should point to the same allocated object,
417+
// restricting `count` to prevent crossing allocation boundaries.
418+
((core::mem::size_of::<T>() == 0) || (kani::mem::same_allocation(self, self.wrapping_offset(count))))
419+
)]
420+
// Postcondition: If `T` is a unit type (`size_of::<T>() == 0`), no allocation check is needed.
421+
// Otherwise, for non-unit types, ensure that `self` and `result` point to the same allocated object,
422+
// verifying that the result remains within the same allocation as `self`.
423+
#[ensures(|result| (core::mem::size_of::<T>() == 0) || kani::mem::same_allocation(self as *const T, *result as *const T))]
414424
pub const unsafe fn offset(self, count: isize) -> *mut T
415425
where
416426
T: Sized,
@@ -955,10 +965,21 @@ impl<T: ?Sized> *mut T {
955965
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
956966
#[inline(always)]
957967
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
958-
#[requires(kani::mem::can_dereference(self))]
959-
// TODO: Determine the valid value range for 'count' and update the precondition accordingly.
960-
#[requires(count == 0)] // This precondition is currently a placeholder.
961-
#[ensures(|result| kani::mem::can_dereference(result))]
968+
#[requires(
969+
// Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`
970+
count.checked_mul(core::mem::size_of::<T>()).is_some() &&
971+
count * core::mem::size_of::<T>() <= isize::MAX as usize &&
972+
// Precondition 2: adding the computed offset to `self` does not cause overflow
973+
(self as isize).checked_add((count * core::mem::size_of::<T>()) as isize).is_some() &&
974+
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
975+
// Otherwise, for non-unit types, `self` and `self.wrapping_add(count)` should point to the same allocated object,
976+
// restricting `count` to prevent crossing allocation boundaries.
977+
((core::mem::size_of::<T>() == 0) || (kani::mem::same_allocation(self, self.wrapping_add(count))))
978+
)]
979+
// Postcondition: If `T` is a unit type (`size_of::<T>() == 0`), no allocation check is needed.
980+
// Otherwise, for non-unit types, ensure that `self` and `result` point to the same allocated object,
981+
// verifying that the result remains within the same allocation as `self`.
982+
#[ensures(|result| (core::mem::size_of::<T>() == 0) || kani::mem::same_allocation(self as *const T, *result as *const T))]
962983
pub const unsafe fn add(self, count: usize) -> Self
963984
where
964985
T: Sized,
@@ -1034,10 +1055,21 @@ impl<T: ?Sized> *mut T {
10341055
#[rustc_allow_const_fn_unstable(unchecked_neg)]
10351056
#[inline(always)]
10361057
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1037-
#[requires(kani::mem::can_dereference(self))]
1038-
// TODO: Determine the valid value range for 'count' and update the precondition accordingly.
1039-
#[requires(count == 0)] // This precondition is currently a placeholder.
1040-
#[ensures(|result| kani::mem::can_dereference(result))]
1058+
#[requires(
1059+
// Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`
1060+
count.checked_mul(core::mem::size_of::<T>()).is_some() &&
1061+
count * core::mem::size_of::<T>() <= isize::MAX as usize &&
1062+
// Precondition 2: subtracting the computed offset from `self` does not cause overflow
1063+
(self as isize).checked_sub((count * core::mem::size_of::<T>()) as isize).is_some() &&
1064+
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
1065+
// Otherwise, for non-unit types, `self` and `self.wrapping_sub(count)` should point to the same allocated object,
1066+
// restricting `count` to prevent crossing allocation boundaries.
1067+
((core::mem::size_of::<T>() == 0) || (kani::mem::same_allocation(self, self.wrapping_sub(count))))
1068+
)]
1069+
// Postcondition: If `T` is a unit type (`size_of::<T>() == 0`), no allocation check is needed.
1070+
// Otherwise, for non-unit types, ensure that `self` and `result` point to the same allocated object,
1071+
// verifying that the result remains within the same allocation as `self`.
1072+
#[ensures(|result| (core::mem::size_of::<T>() == 0) || kani::mem::same_allocation(self as *const T, *result as *const T))]
10411073
pub const unsafe fn sub(self, count: usize) -> Self
10421074
where
10431075
T: Sized,
@@ -2219,102 +2251,120 @@ impl<T: ?Sized> PartialOrd for *mut T {
22192251
mod verify {
22202252
use crate::kani;
22212253

2222-
macro_rules! generate_mut_add_and_sub_harness {
2223-
($type:ty, $proof_name:ident, $func_name:ident) => {
2224-
#[kani::proof_for_contract(<*mut $type>::$func_name)]
2254+
macro_rules! generate_mut_arithmetic_harness {
2255+
($type:ty, $proof_name:ident, add) => {
2256+
#[kani::proof_for_contract(<*mut $type>::add)]
22252257
pub fn $proof_name() {
22262258
let mut test_val: $type = kani::any::<$type>();
2259+
let offset: usize = kani::any();
2260+
let count: usize = kani::any();
2261+
kani::assume(offset <= 1);
2262+
22272263
let test_ptr: *mut $type = &mut test_val;
2264+
let ptr_with_offset: *mut $type = test_ptr.wrapping_add(offset);
2265+
unsafe {
2266+
ptr_with_offset.add(count);
2267+
}
2268+
}
2269+
};
2270+
($type:ty, $proof_name:ident, sub) => {
2271+
#[kani::proof_for_contract(<*mut $type>::sub)]
2272+
pub fn $proof_name() {
2273+
let mut test_val: $type = kani::any::<$type>();
2274+
let offset: usize = kani::any();
22282275
let count: usize = kani::any();
2276+
kani::assume(offset <= 1);
2277+
2278+
let test_ptr: *mut $type = &mut test_val;
2279+
let ptr_with_offset: *mut $type = test_ptr.wrapping_add(offset);
2280+
unsafe {
2281+
ptr_with_offset.sub(count);
2282+
}
2283+
}
2284+
};
2285+
($type:ty, $proof_name:ident, offset) => {
2286+
#[kani::proof_for_contract(<*mut $type>::offset)]
2287+
pub fn $proof_name() {
2288+
let mut test_val: $type = kani::any::<$type>();
2289+
let offset: usize = kani::any();
2290+
let count: isize = kani::any();
2291+
kani::assume(offset <= 1);
2292+
2293+
let test_ptr: *mut $type = &mut test_val;
2294+
let ptr_with_offset: *mut $type = test_ptr.wrapping_add(offset);
22292295
unsafe {
2230-
test_ptr.$func_name(count);
2296+
ptr_with_offset.offset(count);
22312297
}
22322298
}
22332299
};
22342300
}
22352301

22362302
// <*mut T>:: add() integer types verification
2237-
generate_mut_add_and_sub_harness!(i8, check_mut_add_i8, add);
2238-
generate_mut_add_and_sub_harness!(i16, check_mut_add_i16, add);
2239-
generate_mut_add_and_sub_harness!(i32, check_mut_add_i32, add);
2240-
generate_mut_add_and_sub_harness!(i64, check_mut_add_i64, add);
2241-
generate_mut_add_and_sub_harness!(i128, check_mut_add_i128, add);
2242-
generate_mut_add_and_sub_harness!(isize, check_mut_add_isize, add);
2243-
generate_mut_add_and_sub_harness!(u8, check_mut_add_u8, add);
2244-
generate_mut_add_and_sub_harness!(u16, check_mut_add_u16, add);
2245-
generate_mut_add_and_sub_harness!(u32, check_mut_add_u32, add);
2246-
generate_mut_add_and_sub_harness!(u64, check_mut_add_u64, add);
2247-
generate_mut_add_and_sub_harness!(u128, check_mut_add_u128, add);
2248-
generate_mut_add_and_sub_harness!(usize, check_mut_add_usize, add);
2303+
generate_mut_arithmetic_harness!(i8, check_mut_add_i8, add);
2304+
generate_mut_arithmetic_harness!(i16, check_mut_add_i16, add);
2305+
generate_mut_arithmetic_harness!(i32, check_mut_add_i32, add);
2306+
generate_mut_arithmetic_harness!(i64, check_mut_add_i64, add);
2307+
generate_mut_arithmetic_harness!(i128, check_mut_add_i128, add);
2308+
generate_mut_arithmetic_harness!(isize, check_mut_add_isize, add);
2309+
generate_mut_arithmetic_harness!(u8, check_mut_add_u8, add);
2310+
generate_mut_arithmetic_harness!(u16, check_mut_add_u16, add);
2311+
generate_mut_arithmetic_harness!(u32, check_mut_add_u32, add);
2312+
generate_mut_arithmetic_harness!(u64, check_mut_add_u64, add);
2313+
generate_mut_arithmetic_harness!(u128, check_mut_add_u128, add);
2314+
generate_mut_arithmetic_harness!(usize, check_mut_add_usize, add);
22492315

22502316
// <*mut T>:: add() unit type verification
2251-
generate_mut_add_and_sub_harness!((), check_mut_add_unit, add);
2317+
generate_mut_arithmetic_harness!((), check_mut_add_unit, add);
22522318

22532319
// <*mut T>:: add() composite types verification
2254-
generate_mut_add_and_sub_harness!((i8, i8), check_mut_add_tuple_1, add);
2255-
generate_mut_add_and_sub_harness!((f64, bool), check_mut_add_tuple_2, add);
2256-
generate_mut_add_and_sub_harness!((i32, f64, bool), check_mut_add_tuple_3, add);
2257-
generate_mut_add_and_sub_harness!((i8, u16, i32, u64, isize), check_mut_add_tuple_4, add);
2320+
generate_mut_arithmetic_harness!((i8, i8), check_mut_add_tuple_1, add);
2321+
generate_mut_arithmetic_harness!((f64, bool), check_mut_add_tuple_2, add);
2322+
generate_mut_arithmetic_harness!((i32, f64, bool), check_mut_add_tuple_3, add);
2323+
generate_mut_arithmetic_harness!((i8, u16, i32, u64, isize), check_mut_add_tuple_4, add);
22582324

22592325
// <*mut T>:: sub() integer types verification
2260-
generate_mut_add_and_sub_harness!(i8, check_mut_sub_i8, sub);
2261-
generate_mut_add_and_sub_harness!(i16, check_mut_sub_i16, sub);
2262-
generate_mut_add_and_sub_harness!(i32, check_mut_sub_i32, sub);
2263-
generate_mut_add_and_sub_harness!(i64, check_mut_sub_i64, sub);
2264-
generate_mut_add_and_sub_harness!(i128, check_mut_sub_i128, sub);
2265-
generate_mut_add_and_sub_harness!(isize, check_mut_sub_isize, sub);
2266-
generate_mut_add_and_sub_harness!(u8, check_mut_sub_u8, sub);
2267-
generate_mut_add_and_sub_harness!(u16, check_mut_sub_u16, sub);
2268-
generate_mut_add_and_sub_harness!(u32, check_mut_sub_u32, sub);
2269-
generate_mut_add_and_sub_harness!(u64, check_mut_sub_u64, sub);
2270-
generate_mut_add_and_sub_harness!(u128, check_mut_sub_u128, sub);
2271-
generate_mut_add_and_sub_harness!(usize, check_mut_sub_usize, sub);
2326+
generate_mut_arithmetic_harness!(i8, check_mut_sub_i8, sub);
2327+
generate_mut_arithmetic_harness!(i16, check_mut_sub_i16, sub);
2328+
generate_mut_arithmetic_harness!(i32, check_mut_sub_i32, sub);
2329+
generate_mut_arithmetic_harness!(i64, check_mut_sub_i64, sub);
2330+
generate_mut_arithmetic_harness!(i128, check_mut_sub_i128, sub);
2331+
generate_mut_arithmetic_harness!(isize, check_mut_sub_isize, sub);
2332+
generate_mut_arithmetic_harness!(u8, check_mut_sub_u8, sub);
2333+
generate_mut_arithmetic_harness!(u16, check_mut_sub_u16, sub);
2334+
generate_mut_arithmetic_harness!(u32, check_mut_sub_u32, sub);
2335+
generate_mut_arithmetic_harness!(u64, check_mut_sub_u64, sub);
2336+
generate_mut_arithmetic_harness!(u128, check_mut_sub_u128, sub);
2337+
generate_mut_arithmetic_harness!(usize, check_mut_sub_usize, sub);
22722338

22732339
// <*mut T>:: sub() unit type verification
2274-
generate_mut_add_and_sub_harness!((), check_mut_sub_unit, sub);
2340+
generate_mut_arithmetic_harness!((), check_mut_sub_unit, sub);
22752341

22762342
// <*mut T>:: sub() composite types verification
2277-
generate_mut_add_and_sub_harness!((i8, i8), check_mut_sub_tuple_1, sub);
2278-
generate_mut_add_and_sub_harness!((f64, bool), check_mut_sub_tuple_2, sub);
2279-
generate_mut_add_and_sub_harness!((i32, f64, bool), check_mut_sub_tuple_3, sub);
2280-
generate_mut_add_and_sub_harness!((i8, u16, i32, u64, isize), check_mut_sub_tuple_4, sub);
2281-
2282-
2283-
// fn <*mut T>::offset verification begin
2284-
macro_rules! generate_mut_offset_harness {
2285-
($type:ty, $proof_name:ident) => {
2286-
#[kani::proof_for_contract(<*mut $type>::offset)]
2287-
pub fn $proof_name() {
2288-
let mut test_val: $type = kani::any::<$type>();
2289-
let test_ptr: *mut $type = &mut test_val;
2290-
let count: isize = kani::any();
2291-
unsafe {
2292-
test_ptr.offset(count);
2293-
}
2294-
}
2295-
};
2296-
}
2297-
2298-
// fn <*mut T>::offset integer types verification
2299-
generate_mut_offset_harness!(i8, check_mut_offset_i8);
2300-
generate_mut_offset_harness!(i16, check_mut_offset_i16);
2301-
generate_mut_offset_harness!(i32, check_mut_offset_i32);
2302-
generate_mut_offset_harness!(i64, check_mut_offset_i64);
2303-
generate_mut_offset_harness!(i128, check_mut_offset_i128);
2304-
generate_mut_offset_harness!(isize, check_mut_offset_isize);
2305-
generate_mut_offset_harness!(u8, check_mut_offset_u8);
2306-
generate_mut_offset_harness!(u16, check_mut_offset_u16);
2307-
generate_mut_offset_harness!(u32, check_mut_offset_u32);
2308-
generate_mut_offset_harness!(u64, check_mut_offset_u64);
2309-
generate_mut_offset_harness!(u128, check_mut_offset_u128);
2310-
generate_mut_offset_harness!(usize, check_mut_offset_usize);
2311-
2312-
// fn <*mut T>::offset unit type verification
2313-
generate_mut_offset_harness!((), check_mut_offset_unit);
2314-
2315-
// fn <*mut T>::offset composite type verification
2316-
generate_mut_offset_harness!((i8, i8), check_mut_offset_tuple_1);
2317-
generate_mut_offset_harness!((f64, bool), check_mut_offset_tuple_2);
2318-
generate_mut_offset_harness!((i32, f64, bool), check_mut_offset_tuple_3);
2319-
generate_mut_offset_harness!((i8, u16, i32, u64, isize), check_mut_offset_tuple_4);
2343+
generate_mut_arithmetic_harness!((i8, i8), check_mut_sub_tuple_1, sub);
2344+
generate_mut_arithmetic_harness!((f64, bool), check_mut_sub_tuple_2, sub);
2345+
generate_mut_arithmetic_harness!((i32, f64, bool), check_mut_sub_tuple_3, sub);
2346+
generate_mut_arithmetic_harness!((i8, u16, i32, u64, isize), check_mut_sub_tuple_4, sub);
2347+
2348+
// fn <*mut T>::offset() integer types verification
2349+
generate_mut_arithmetic_harness!(i8, check_mut_offset_i8, offset);
2350+
generate_mut_arithmetic_harness!(i16, check_mut_offset_i16, offset);
2351+
generate_mut_arithmetic_harness!(i32, check_mut_offset_i32, offset);
2352+
generate_mut_arithmetic_harness!(i64, check_mut_offset_i64, offset);
2353+
generate_mut_arithmetic_harness!(i128, check_mut_offset_i128, offset);
2354+
generate_mut_arithmetic_harness!(isize, check_mut_offset_isize, offset);
2355+
generate_mut_arithmetic_harness!(u8, check_mut_offset_u8, offset);
2356+
generate_mut_arithmetic_harness!(u16, check_mut_offset_u16, offset);
2357+
generate_mut_arithmetic_harness!(u32, check_mut_offset_u32, offset);
2358+
generate_mut_arithmetic_harness!(u64, check_mut_offset_u64, offset);
2359+
generate_mut_arithmetic_harness!(u128, check_mut_offset_u128, offset);
2360+
generate_mut_arithmetic_harness!(usize, check_mut_offset_usize, offset);
2361+
2362+
// fn <*mut T>::offset() unit type verification
2363+
generate_mut_arithmetic_harness!((), check_mut_offset_unit, offset);
2364+
2365+
// fn <*mut T>::offset() composite type verification
2366+
generate_mut_arithmetic_harness!((i8, i8), check_mut_offset_tuple_1, offset);
2367+
generate_mut_arithmetic_harness!((f64, bool), check_mut_offset_tuple_2, offset);
2368+
generate_mut_arithmetic_harness!((i32, f64, bool), check_mut_offset_tuple_3, offset);
2369+
generate_mut_arithmetic_harness!((i8, u16, i32, u64, isize), check_mut_offset_tuple_4, offset);
23202370
}

0 commit comments

Comments
 (0)