Skip to content

Commit db064d4

Browse files
add loop invariant and harness for slice repeat
1 parent f66ba41 commit db064d4

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

library/alloc/src/slice.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ pub use core::slice::{from_mut_ptr_range, from_ptr_range};
5252
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
5353
#[unstable(feature = "slice_range", issue = "76393")]
5454
pub use core::slice::{range, try_range};
55+
#[cfg(kani)]
56+
use crate::kani;
57+
#[cfg(kani)]
58+
use core::ptr::slice_from_raw_parts;
5559

5660
////////////////////////////////////////////////////////////////////////////////
5761
// Basic slice extension methods
@@ -524,6 +528,18 @@ impl<T> [T] {
524528
{
525529
let mut m = n >> 1;
526530
// If `m > 0`, there are remaining bits up to the leftmost '1'.
531+
#[cfg(kani)]
532+
let buf_ptr= slice_from_raw_parts(buf.as_ptr(), capacity);
533+
#[cfg(kani)]
534+
let len_ptr = unsafe {(&buf as *const Vec<T> as *const usize).add(2)};
535+
#[kani::loop_invariant(
536+
kani::mem::same_allocation(buf.as_ptr(), buf.as_ptr().wrapping_add(capacity)) &&
537+
unsafe {*len_ptr <= T::MAX_SLICE_LEN} &&
538+
unsafe {*len_ptr <= capacity} &&
539+
m.leading_zeros() > n.leading_zeros() &&
540+
unsafe {*len_ptr == sef.len() * (1usize << (m.leading_zeros() - n.leading_zeros() - 1))}
541+
)]
542+
#[kani::loop_modifies(&m, buf_ptr, len_ptr)]
527543
while m > 0 {
528544
// `buf.extend(buf)`:
529545
unsafe {
@@ -867,3 +883,23 @@ impl<T> sort::stable::BufGuard<T> for Vec<T> {
867883
self.spare_capacity_mut()
868884
}
869885
}
886+
887+
#[cfg(kani)]
888+
#[unstable(feature = "kani", issue = "none")]
889+
pub mod slice_verify {
890+
use super::*;
891+
892+
#[kani::proof]
893+
fn check_repeat_u8() {
894+
let mut a: [u8; 10] = kani::any();
895+
let n = kani::any_where(|i| *i < 10);
896+
let _result = repeat(a.as_slice(), n);
897+
}
898+
899+
#[kani::proof]
900+
fn check_repeat_u16() {
901+
let mut a: [u16; 10] = kani::any();
902+
let n = kani::any_where(|i| *i < 10);
903+
let _result = repeat(a.as_slice(), n);
904+
}
905+
}

0 commit comments

Comments
 (0)