forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Contract and harness for copy_to, copy_to_nonoverlapping, copy_from, and copy_from_nonoverlapping #149
Open
Dhvani-Kapadia
wants to merge
8
commits into
model-checking:main
Choose a base branch
from
danielhumanmod:dhvani_mem
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Contract and harness for copy_to, copy_to_nonoverlapping, copy_from, and copy_from_nonoverlapping #149
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
16ecdb9
adding contracts for 4 memory operations
Dhvani-Kapadia 50521ab
Update non_null.rs
Dhvani-Kapadia 5e7ba89
Update non_null.rs
Dhvani-Kapadia dac703d
Update non_null.rs
Dhvani-Kapadia a87c214
Merge conflict resolution
Dhvani-Kapadia 90ae95e
Merge branch 'dhvani_mem' of https://github.com/danielhumanmod/verify…
Dhvani-Kapadia d024fc2
feedback
Dhvani-Kapadia 2da2f74
removing log files
Dhvani-Kapadia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ use crate::slice::{self, SliceIndex}; | |
use crate::ub_checks::assert_unsafe_precondition; | ||
use crate::{fmt, hash, intrinsics, ptr}; | ||
use safety::{ensures, requires}; | ||
|
||
use crate::{ub_checks}; | ||
|
||
#[cfg(kani)] | ||
use crate::kani; | ||
|
@@ -965,6 +965,13 @@ impl<T: ?Sized> NonNull<T> { | |
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces | ||
#[stable(feature = "non_null_convenience", since = "1.80.0")] | ||
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] | ||
#[requires(count.checked_mul(core::mem::size_of::<T>()).map_or(false, |size| size <= isize::MAX as usize) | ||
&& ub_checks::can_dereference(self.as_ptr() as *const MaybeUninit<T>) | ||
&& ub_checks::can_write(dest.as_ptr()) | ||
&& ub_checks::can_write(dest.as_ptr().add(count)))] | ||
#[ensures(|result: &()| ub_checks::can_dereference(self.as_ptr() as *const u8) | ||
&& ub_checks::can_dereference(dest.as_ptr() as *const u8))] | ||
#[kani::modifies(dest.as_ptr())] | ||
pub const unsafe fn copy_to(self, dest: NonNull<T>, count: usize) | ||
where | ||
T: Sized, | ||
|
@@ -985,6 +992,14 @@ impl<T: ?Sized> NonNull<T> { | |
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces | ||
#[stable(feature = "non_null_convenience", since = "1.80.0")] | ||
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] | ||
#[requires(count.checked_mul(core::mem::size_of::<T>()).map_or(false, |size| size <= isize::MAX as usize) | ||
&& ub_checks::can_dereference(self.as_ptr() as *const MaybeUninit<T>) | ||
&& ub_checks::can_write(dest.as_ptr()) | ||
&& ub_checks::can_write(dest.as_ptr().add(count)) | ||
&& (self.as_ptr() as usize).abs_diff(dest.as_ptr() as usize) >= count * core::mem::size_of::<T>())] | ||
#[ensures(|result: &()| ub_checks::can_dereference(self.as_ptr() as *const u8) | ||
&& ub_checks::can_dereference(dest.as_ptr() as *const u8))] | ||
#[kani::modifies(dest.as_ptr())] | ||
pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull<T>, count: usize) | ||
where | ||
T: Sized, | ||
|
@@ -1005,6 +1020,14 @@ impl<T: ?Sized> NonNull<T> { | |
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces | ||
#[stable(feature = "non_null_convenience", since = "1.80.0")] | ||
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] | ||
#[requires (count.checked_mul(core::mem::size_of::<T>()).map_or(false, |size| size <= isize::MAX as usize | ||
&& ub_checks::can_dereference(src.as_ptr() as *const MaybeUninit<T>) | ||
&& ub_checks::can_write(self.as_ptr()) | ||
&& ub_checks::can_write (self.as_ptr().add(count))) | ||
&& (src.as_ptr() as usize).abs_diff(self.as_ptr() as usize) >= count * core::mem::size_of::<T>())] | ||
#[ensures (|result: &()| ub_checks::can_dereference(src.as_ptr() as *const u8) | ||
&& ub_checks::can_dereference(self.as_ptr()))] | ||
#[kani::modifies(self.as_ptr())] | ||
pub const unsafe fn copy_from(self, src: NonNull<T>, count: usize) | ||
where | ||
T: Sized, | ||
|
@@ -1025,6 +1048,14 @@ impl<T: ?Sized> NonNull<T> { | |
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces | ||
#[stable(feature = "non_null_convenience", since = "1.80.0")] | ||
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] | ||
#[requires (count.checked_mul(core::mem::size_of::<T>()).map_or(false, |size| size <= isize::MAX as usize | ||
&& ub_checks::can_dereference(src.as_ptr() as *const MaybeUninit<T>) | ||
&& ub_checks::can_write(self.as_ptr()) | ||
&& ub_checks::can_write(self.as_ptr().add(count))) | ||
&& (self.as_ptr() as usize).abs_diff(src.as_ptr() as usize) >= count * core::mem::size_of::<T>())]//The source and destination regions do not overlap. | ||
#[ensures (|result: &()| ub_checks::can_dereference(src.as_ptr() as *const u8) | ||
&& ub_checks::can_dereference(self.as_ptr()))] | ||
#[kani::modifies(self.as_ptr())] | ||
pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull<T>, count: usize) | ||
where | ||
T: Sized, | ||
|
@@ -1811,6 +1842,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> { | |
mod verify { | ||
use super::*; | ||
use crate::ptr::null_mut; | ||
use kani::PointerGenerator; | ||
|
||
// pub const unsafe fn new_unchecked(ptr: *mut T) -> Self | ||
#[kani::proof_for_contract(NonNull::new_unchecked)] | ||
|
@@ -1826,7 +1858,68 @@ mod verify { | |
pub fn non_null_check_new() { | ||
let mut x: i32 = kani::any(); | ||
let xptr = &mut x; | ||
let maybe_null_ptr = if kani::any() { xptr as *mut i32 } else { null_mut() }; | ||
let maybe_null_ptr = if kani::any() { xptr as *mut i32 } else { null_mut() }; | ||
let _ = NonNull::new(maybe_null_ptr); | ||
} | ||
|
||
#[kani::proof_for_contract(NonNull::<T>::copy_to)] | ||
pub fn non_null_check_copy_to() { | ||
// PointerGenerator instance | ||
let mut generator = PointerGenerator::<16>::new(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How the capacity of the generator affect the running time of the proof? Can we use the maximum capacity, e.g., |
||
// Generate arbitrary pointers for src and dest | ||
let src_ptr = generator.any_in_bounds::<i32>().ptr; | ||
let dest_ptr = generator.any_in_bounds::<i32>().ptr; | ||
// Wrap the raw pointers in NonNull | ||
let src = NonNull::new(src_ptr).unwrap(); | ||
let dest = NonNull::new(dest_ptr).unwrap(); | ||
// Generate an arbitrary count using kani::any | ||
let count: usize = kani::any(); | ||
unsafe { src.copy_to(dest, count);} | ||
} | ||
|
||
#[kani::proof_for_contract(NonNull::<T>::copy_from)] | ||
pub fn non_null_check_copy_from() { | ||
// Create source and destination values | ||
let mut src_value: i32 = kani::any(); | ||
let mut dest_value: i32 = 0; | ||
|
||
// Create NonNull pointers | ||
let src = NonNull::new(&mut src_value as *mut i32).unwrap(); | ||
let dest = NonNull::new(&mut dest_value as *mut i32).unwrap(); | ||
|
||
//count is 1 as working with single i32 value | ||
let count = 1; | ||
unsafe { | ||
src.copy_from(dest, count); | ||
} | ||
} | ||
#[kani::proof_for_contract(NonNull::<T>::copy_to_nonoverlapping)] | ||
pub fn non_null_check_copy_to_nonoverlapping() { | ||
let mut src_value: i32 = kani::any(); | ||
let mut dest_value: i32 = 0; | ||
|
||
let src = NonNull::new(&mut src_value as *mut i32).unwrap(); | ||
let dest = NonNull::new(&mut dest_value as *mut i32).unwrap(); | ||
|
||
//count represents no of elements to copy | ||
let count = 1; | ||
unsafe { | ||
src.copy_to_nonoverlapping(dest, count); | ||
} | ||
} | ||
#[kani::proof_for_contract(NonNull::<T>::copy_from_nonoverlapping)] | ||
pub fn non_null_check_copy_from_nonoverlapping() { | ||
let mut src_value: i32 = kani::any(); | ||
let mut dest_value: i32 = 0; | ||
|
||
let src = NonNull::new(&mut src_value as *mut i32).unwrap(); | ||
let dest = NonNull::new(&mut dest_value as *mut i32).unwrap(); | ||
Dhvani-Kapadia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
//count represents no of elements to copy | ||
let count = 1; | ||
|
||
unsafe { | ||
dest.copy_from_nonoverlapping(src, count); | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.