@@ -43,6 +43,9 @@ use crate::convert::TryInto as _;
4343use crate :: slice:: memchr;
4444use crate :: { cmp, fmt} ;
4545
46+ #[ cfg( kani) ]
47+ use crate :: kani;
48+
4649// Pattern
4750
4851/// A string pattern.
@@ -1926,6 +1929,10 @@ unsafe fn small_slice_eq(x: &[u8], y: &[u8]) -> bool {
19261929 unsafe {
19271930 let ( mut px, mut py) = ( x. as_ptr ( ) , y. as_ptr ( ) ) ;
19281931 let ( pxend, pyend) = ( px. add ( x. len ( ) - 4 ) , py. add ( y. len ( ) - 4 ) ) ;
1932+ #[ cfg_attr( kani, kani:: loop_invariant( same_allocation( x. as_ptr( ) , px) && same_allocation( y. as_ptr( ) , py)
1933+ && px as isize >= x. as_ptr( ) as isize
1934+ && py as isize >= y. as_ptr( ) as isize
1935+ && px as isize - x. as_ptr( ) as isize == ( py as isize - y. as_ptr( ) as isize ) ) ) ]
19291936 while px < pxend {
19301937 let vx = ( px as * const u32 ) . read_unaligned ( ) ;
19311938 let vy = ( py as * const u32 ) . read_unaligned ( ) ;
@@ -1940,3 +1947,17 @@ unsafe fn small_slice_eq(x: &[u8], y: &[u8]) -> bool {
19401947 vx == vy
19411948 }
19421949}
1950+
1951+ #[ cfg( kani) ]
1952+ #[ unstable( feature = "kani" , issue = "none" ) ]
1953+ pub mod verify {
1954+ #[ cfg( all( target_arch = "x86_64" , target_feature = "sse2" ) ) ] // only called on x86
1955+ #[ kani:: proof]
1956+ pub fn check_small_slice_eq ( ) {
1957+ let _ = Box :: new ( 0 ) ;
1958+ const ARR_SIZE : usize = 1000 ;
1959+ let x: [ i32 ; ARR_SIZE ] = kani:: any ( ) ;
1960+ let y: [ i32 ; ARR_SIZE ] = kani:: any ( ) ;
1961+ small_slice_eq ( x, y) ;
1962+ }
1963+ }
0 commit comments