Skip to content

Commit

Permalink
Avoid undefined behavior in AnySlice::new() (model-checking#2288)
Browse files Browse the repository at this point in the history
Signed-off-by: Felipe R. Monteiro <[email protected]>
  • Loading branch information
feliperodri authored Mar 9, 2023
1 parent 878e5b9 commit 4b925fd
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
2 changes: 1 addition & 1 deletion library/kani/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl<T, const MAX_SLICE_LENGTH: usize> AnySlice<T, MAX_SLICE_LENGTH> {
// *(ptr as *mut T).add(i) = any();
// }
while i < any_slice.slice_len && i < MAX_SLICE_LENGTH {
*any_slice.ptr.add(i) = any();
std::ptr::write(any_slice.ptr.add(i), any());
i += 1;
}
}
Expand Down
25 changes: 25 additions & 0 deletions tests/kani/Slice/slice-drop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

// Assigning to a memory location via pointer dereferencing causes Drop::drop to be called for the location to which the pointer points.
// Here, kani::Arbitrary implementation for MyStruct deterministically sets MyStruct.0 to 1.
// We check whether AnySlice will properly initialize memory making the assertion in drop() to pass.

struct MyStruct(i32);

impl Drop for MyStruct {
fn drop(&mut self) {
assert!(self.0 == 1);
}
}

impl kani::Arbitrary for MyStruct {
fn any() -> Self {
MyStruct(1)
}
}

#[kani::proof]
fn my_proof() {
let my_slice = kani::slice::any_slice::<MyStruct, 1>();
}

0 comments on commit 4b925fd

Please sign in to comment.