Skip to content

Commit c1b4488

Browse files
Merge branch 'main' of https://github.com/danielhumanmod/verify-rust-std into daniel/byte_operation
2 parents fbccaa2 + 716c6af commit c1b4488

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

.github/pull_requests.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ members = [
1616
"robdockins",
1717
"HuStmpHrrr",
1818
"Eh2406",
19-
"jswrenn"
19+
"jswrenn",
20+
"havelund",
21+
"jorajeev"
2022
]

library/core/src/ptr/non_null.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,12 @@ impl<T: ?Sized> NonNull<T> {
674674
#[stable(feature = "non_null_convenience", since = "1.80.0")]
675675
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
676676
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
677+
#[requires(
678+
count.checked_mul(core::mem::size_of::<T>()).is_some() &&
679+
count * core::mem::size_of::<T>() <= isize::MAX as usize &&
680+
kani::mem::same_allocation(self.as_ptr(), self.as_ptr().wrapping_sub(count))
681+
)]
682+
#[ensures(|result: &NonNull<T>| result.as_ptr() == self.as_ptr().offset(-(count as isize)))]
677683
pub const unsafe fn sub(self, count: usize) -> Self
678684
where
679685
T: Sized,
@@ -803,6 +809,11 @@ impl<T: ?Sized> NonNull<T> {
803809
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
804810
#[stable(feature = "non_null_convenience", since = "1.80.0")]
805811
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
812+
#[requires(
813+
(kani::mem::same_allocation(self.as_ptr(), origin.as_ptr()) &&
814+
((self.as_ptr().addr() - origin.as_ptr().addr()) % core::mem::size_of::<T>() == 0))
815+
)] // Ensure both pointers meet safety conditions for offset_from
816+
#[ensures(|result: &isize| *result == (self.as_ptr() as isize - origin.as_ptr() as isize) / core::mem::size_of::<T>() as isize)]
806817
pub const unsafe fn offset_from(self, origin: NonNull<T>) -> isize
807818
where
808819
T: Sized,
@@ -901,6 +912,13 @@ impl<T: ?Sized> NonNull<T> {
901912
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
902913
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
903914
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
915+
#[requires(
916+
self.as_ptr().addr().checked_sub(subtracted.as_ptr().addr()).is_some() &&
917+
kani::mem::same_allocation(self.as_ptr(), subtracted.as_ptr()) &&
918+
(self.as_ptr().addr()) >= (subtracted.as_ptr().addr()) &&
919+
(self.as_ptr().addr() - subtracted.as_ptr().addr()) % core::mem::size_of::<T>() == 0
920+
)]
921+
#[ensures(|result: &usize| *result == self.as_ptr().offset_from(subtracted.as_ptr()) as usize)]
904922
pub const unsafe fn sub_ptr(self, subtracted: NonNull<T>) -> usize
905923
where
906924
T: Sized,
@@ -2402,6 +2420,75 @@ mod verify {
24022420
let result = non_null_ptr.is_aligned_to(align);
24032421
}
24042422

2423+
#[kani::proof_for_contract(NonNull::sub)]
2424+
pub fn non_null_check_sub() {
2425+
const SIZE: usize = 10000;
2426+
let mut generator = kani::PointerGenerator::<SIZE>::new();
2427+
// Get a raw pointer from the generator within bounds
2428+
let raw_ptr: *mut i32 = generator.any_in_bounds().ptr;
2429+
// Create a non-null pointer from the raw pointer
2430+
let ptr = unsafe { NonNull::new(raw_ptr).unwrap() };
2431+
// Create a non-deterministic count value
2432+
let count: usize = kani::any();
2433+
2434+
unsafe {
2435+
let result = ptr.sub(count);
2436+
}
2437+
}
2438+
2439+
#[kani::proof_for_contract(NonNull::sub_ptr)]
2440+
pub fn non_null_check_sub_ptr() {
2441+
const SIZE: usize = core::mem::size_of::<i32>() * 1000;
2442+
let mut generator1 = kani::PointerGenerator::<SIZE>::new();
2443+
let mut generator2 = kani::PointerGenerator::<SIZE>::new();
2444+
2445+
let ptr: *mut i32 = if kani::any() {
2446+
generator1.any_in_bounds().ptr as *mut i32
2447+
} else {
2448+
generator2.any_in_bounds().ptr as *mut i32
2449+
};
2450+
2451+
let origin: *mut i32 = if kani::any() {
2452+
generator1.any_in_bounds().ptr as *mut i32
2453+
} else {
2454+
generator2.any_in_bounds().ptr as *mut i32
2455+
};
2456+
2457+
let ptr_nonnull = unsafe { NonNull::new(ptr).unwrap() };
2458+
let origin_nonnull = unsafe { NonNull::new(origin).unwrap() };
2459+
2460+
unsafe {
2461+
let distance = ptr_nonnull.sub_ptr(origin_nonnull);
2462+
}
2463+
}
2464+
2465+
#[kani::proof_for_contract(NonNull::offset_from)]
2466+
#[kani::should_panic]
2467+
pub fn non_null_check_offset_from() {
2468+
const SIZE: usize = core::mem::size_of::<i32>() * 1000;
2469+
let mut generator1 = kani::PointerGenerator::<SIZE>::new();
2470+
let mut generator2 = kani::PointerGenerator::<SIZE>::new();
2471+
2472+
let ptr: *mut i32 = if kani::any() {
2473+
generator1.any_in_bounds().ptr as *mut i32
2474+
} else {
2475+
generator2.any_in_bounds().ptr as *mut i32
2476+
};
2477+
2478+
let origin: *mut i32 = if kani::any() {
2479+
generator1.any_in_bounds().ptr as *mut i32
2480+
} else {
2481+
generator2.any_in_bounds().ptr as *mut i32
2482+
};
2483+
2484+
let ptr_nonnull = unsafe { NonNull::new(ptr).unwrap() };
2485+
let origin_nonnull = unsafe { NonNull::new(origin).unwrap() };
2486+
2487+
unsafe {
2488+
let distance = ptr_nonnull.offset_from(origin_nonnull);
2489+
}
2490+
}
2491+
24052492
#[kani::proof_for_contract(NonNull::byte_add)]
24062493
pub fn non_null_byte_add_proof() {
24072494
const ARR_SIZE: usize = mem::size_of::<i32>() * 1000;

0 commit comments

Comments
 (0)