Skip to content

Commit 5e44e6e

Browse files
Contracts & Harnesses for len, is_empty, is_aligned, and is_aligned_to (#128)
Changes added contract and harness for len, is_empty, is_aligned, and is_aligned_to in the non-null library. ``` Complete - 4 successfully verified harnesses, 0 failures, 4 total. ``` --------- Co-authored-by: Carolyn Zech <[email protected]>
1 parent b81906d commit 5e44e6e

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

library/core/src/ptr/non_null.rs

+77
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,7 @@ impl<T: ?Sized> NonNull<T> {
13871387
#[must_use]
13881388
#[stable(feature = "pointer_is_aligned", since = "1.79.0")]
13891389
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
1390+
#[ensures(|result: &bool| *result == (self.as_ptr().addr() % core::mem::align_of::<T>() == 0))]
13901391
pub const fn is_aligned(self) -> bool
13911392
where
13921393
T: Sized,
@@ -1502,6 +1503,8 @@ impl<T: ?Sized> NonNull<T> {
15021503
#[must_use]
15031504
#[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
15041505
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
1506+
#[requires(align.is_power_of_two())]
1507+
#[ensures(|result: &bool| *result == (self.as_ptr().addr() % align == 0))] // Ensure the returned value is correct based on the given alignment
15051508
pub const fn is_aligned_to(self, align: usize) -> bool {
15061509
self.pointer.is_aligned_to(align)
15071510
}
@@ -1881,6 +1884,14 @@ mod verify {
18811884
use crate::ptr::null_mut;
18821885
use kani::PointerGenerator;
18831886

1887+
impl<T> kani::Arbitrary for NonNull<T> {
1888+
fn any() -> Self {
1889+
let ptr: *mut T = kani::any::<usize>() as *mut T;
1890+
kani::assume(!ptr.is_null());
1891+
NonNull::new(ptr).expect("Non-null pointer expected")
1892+
}
1893+
}
1894+
18841895
// pub const unsafe fn new_unchecked(ptr: *mut T) -> Self
18851896
#[kani::proof_for_contract(NonNull::new_unchecked)]
18861897
pub fn non_null_check_new_unchecked() {
@@ -2179,4 +2190,70 @@ mod verify {
21792190
assert_eq!(old_b, new_a);
21802191
}
21812192
}
2193+
2194+
#[kani::proof]
2195+
pub fn non_null_check_len() {
2196+
// Create a non-deterministic NonNull pointer using kani::any()
2197+
let non_null_ptr: NonNull<i8> = kani::any();
2198+
// Create a non-deterministic size using kani::any()
2199+
let size: usize = kani::any();
2200+
// Create a NonNull slice from the non-null pointer and size
2201+
let non_null_slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(non_null_ptr, size);
2202+
2203+
// Perform the length check
2204+
let len = non_null_slice.len();
2205+
assert!(len == size);
2206+
}
2207+
2208+
#[kani::proof]
2209+
pub fn non_null_check_is_empty() {
2210+
// Create a non-deterministic NonNull pointer using kani::any()
2211+
let non_null_ptr: NonNull<i8> = kani::any();
2212+
// Create a non-deterministic size using kani::any(), constrained to zero
2213+
let size: usize = 0;
2214+
2215+
// Create a NonNull slice from the non-null pointer and size
2216+
let non_null_slice: NonNull<[i8]> = unsafe { NonNull::slice_from_raw_parts(non_null_ptr, size) };
2217+
2218+
// Perform the is_empty check
2219+
let is_empty = non_null_slice.is_empty();
2220+
assert!(is_empty);
2221+
}
2222+
2223+
#[kani::proof_for_contract(NonNull::is_aligned)]
2224+
pub fn non_null_slice_is_aligned_check() {
2225+
// Create a non-deterministic NonNull pointer using kani::any()
2226+
let non_null_ptr: NonNull<i32> = kani::any();
2227+
2228+
// Perform the alignment check
2229+
let result = non_null_ptr.is_aligned();
2230+
2231+
}
2232+
2233+
#[kani::proof_for_contract(NonNull::is_aligned_to)]
2234+
pub fn non_null_check_is_aligned_to() {
2235+
// Create a non-deterministic NonNull pointer using kani::any()
2236+
let non_null_ptr: NonNull<i32> = kani::any();
2237+
2238+
// Create a non-deterministic alignment using kani::any()
2239+
let align: usize = kani::any();
2240+
kani::assume(align > 0); // Ensure alignment is greater than zero
2241+
2242+
// Perform the alignment check
2243+
let result = non_null_ptr.is_aligned_to(align);
2244+
2245+
}
2246+
2247+
#[kani::proof]
2248+
#[kani::should_panic] // Add this if we expect a panic when the alignment is invalid
2249+
pub fn non_null_check_is_aligned_to_no_power_two() {
2250+
// Create a non-deterministic NonNull pointer using kani::any()
2251+
let non_null_ptr: NonNull<i32> = kani::any();
2252+
2253+
// Create a non-deterministic alignment value using kani::any()
2254+
let align: usize = kani::any();
2255+
2256+
// Perform the alignment check
2257+
let result = non_null_ptr.is_aligned_to(align);
2258+
}
21822259
}

0 commit comments

Comments
 (0)