@@ -3,6 +3,10 @@ use crate::cmp::Ordering::{Equal, Greater, Less};
3
3
use crate :: intrinsics:: const_eval_select;
4
4
use crate :: mem:: SizedTypeProperties ;
5
5
use crate :: slice:: { self , SliceIndex } ;
6
+ use safety:: { ensures, requires} ;
7
+
8
+ #[ cfg( kani) ]
9
+ use crate :: kani;
6
10
7
11
impl < T : ?Sized > * const T {
8
12
/// Returns `true` if the pointer is null.
@@ -667,6 +671,16 @@ impl<T: ?Sized> *const T {
667
671
#[ rustc_const_stable( feature = "const_ptr_offset_from" , since = "1.65.0" ) ]
668
672
#[ inline]
669
673
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
674
+ #[ requires(
675
+ // Ensures subtracting `origin` from `self` doesn't overflow
676
+ ( self as isize ) . checked_sub( origin as isize ) . is_some( ) &&
677
+ // Ensure the distance between `self` and `origin` is aligned to `T`
678
+ ( self as isize - origin as isize ) % ( mem:: size_of:: <T >( ) as isize ) == 0 &&
679
+ // Ensure both pointers are in the same allocation or are pointing to the same address
680
+ ( self as isize == origin as isize || kani:: mem:: same_allocation( self , origin) )
681
+ ) ]
682
+ // The result should equal the distance in terms of elements of type `T` as per the documentation above
683
+ #[ ensures( |result| * result == ( self as isize - origin as isize ) / ( mem:: size_of:: <T >( ) as isize ) ) ]
670
684
pub const unsafe fn offset_from ( self , origin : * const T ) -> isize
671
685
where
672
686
T : Sized ,
@@ -1899,3 +1913,149 @@ impl<T: ?Sized> PartialOrd for *const T {
1899
1913
* self >= * other
1900
1914
}
1901
1915
}
1916
+
1917
+ #[ cfg( kani) ]
1918
+ #[ unstable( feature = "kani" , issue = "none" ) ]
1919
+ mod verify {
1920
+ use crate :: kani;
1921
+ use core:: mem;
1922
+ use kani:: PointerGenerator ;
1923
+
1924
+ // Proof for unit size will panic as offset_from needs the pointee size to be greater then 0
1925
+ #[ kani:: proof_for_contract( <* const ( ) >:: offset_from) ]
1926
+ #[ kani:: should_panic]
1927
+ pub fn check_const_offset_from_unit ( ) {
1928
+ let val: ( ) = ( ) ;
1929
+ let src_ptr: * const ( ) = & val;
1930
+ let dest_ptr: * const ( ) = & val;
1931
+ unsafe {
1932
+ dest_ptr. offset_from ( src_ptr) ;
1933
+ }
1934
+ }
1935
+
1936
+ // Array size bound for kani::any_array
1937
+ const ARRAY_LEN : usize = 40 ;
1938
+
1939
+ macro_rules! generate_offset_from_harness {
1940
+ ( $type: ty, $proof_name1: ident, $proof_name2: ident) => {
1941
+ // Proof for a single element
1942
+ #[ kani:: proof_for_contract( <* const $type>:: offset_from) ]
1943
+ pub fn $proof_name1( ) {
1944
+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
1945
+ let mut generator1 = PointerGenerator :: <gen_size>:: new( ) ;
1946
+ let mut generator2 = PointerGenerator :: <gen_size>:: new( ) ;
1947
+ let ptr1: * const $type = generator1. any_in_bounds( ) . ptr;
1948
+ let ptr2: * const $type = if kani:: any( ) {
1949
+ generator1. any_alloc_status( ) . ptr
1950
+ } else {
1951
+ generator2. any_alloc_status( ) . ptr
1952
+ } ;
1953
+
1954
+ unsafe {
1955
+ ptr1. offset_from( ptr2) ;
1956
+ }
1957
+ }
1958
+
1959
+ // Proof for large arrays
1960
+ #[ kani:: proof_for_contract( <* const $type>:: offset_from) ]
1961
+ pub fn $proof_name2( ) {
1962
+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
1963
+ let mut generator1 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
1964
+ let mut generator2 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
1965
+ let ptr1: * const $type = generator1. any_in_bounds( ) . ptr;
1966
+ let ptr2: * const $type = if kani:: any( ) {
1967
+ generator1. any_alloc_status( ) . ptr
1968
+ } else {
1969
+ generator2. any_alloc_status( ) . ptr
1970
+ } ;
1971
+
1972
+ unsafe {
1973
+ ptr1. offset_from( ptr2) ;
1974
+ }
1975
+ }
1976
+ } ;
1977
+ }
1978
+
1979
+ generate_offset_from_harness ! (
1980
+ u8 ,
1981
+ check_const_offset_from_u8,
1982
+ check_const_offset_from_u8_arr
1983
+ ) ;
1984
+ generate_offset_from_harness ! (
1985
+ u16 ,
1986
+ check_const_offset_from_u16,
1987
+ check_const_offset_from_u16_arr
1988
+ ) ;
1989
+ generate_offset_from_harness ! (
1990
+ u32 ,
1991
+ check_const_offset_from_u32,
1992
+ check_const_offset_from_u32_arr
1993
+ ) ;
1994
+ generate_offset_from_harness ! (
1995
+ u64 ,
1996
+ check_const_offset_from_u64,
1997
+ check_const_offset_from_u64_arr
1998
+ ) ;
1999
+ generate_offset_from_harness ! (
2000
+ u128 ,
2001
+ check_const_offset_from_u128,
2002
+ check_const_offset_from_u128_arr
2003
+ ) ;
2004
+ generate_offset_from_harness ! (
2005
+ usize ,
2006
+ check_const_offset_from_usize,
2007
+ check_const_offset_from_usize_arr
2008
+ ) ;
2009
+
2010
+ generate_offset_from_harness ! (
2011
+ i8 ,
2012
+ check_const_offset_from_i8,
2013
+ check_const_offset_from_i8_arr
2014
+ ) ;
2015
+ generate_offset_from_harness ! (
2016
+ i16 ,
2017
+ check_const_offset_from_i16,
2018
+ check_const_offset_from_i16_arr
2019
+ ) ;
2020
+ generate_offset_from_harness ! (
2021
+ i32 ,
2022
+ check_const_offset_from_i32,
2023
+ check_const_offset_from_i32_arr
2024
+ ) ;
2025
+ generate_offset_from_harness ! (
2026
+ i64 ,
2027
+ check_const_offset_from_i64,
2028
+ check_const_offset_from_i64_arr
2029
+ ) ;
2030
+ generate_offset_from_harness ! (
2031
+ i128 ,
2032
+ check_const_offset_from_i128,
2033
+ check_const_offset_from_i128_arr
2034
+ ) ;
2035
+ generate_offset_from_harness ! (
2036
+ isize ,
2037
+ check_const_offset_from_isize,
2038
+ check_const_offset_from_isize_arr
2039
+ ) ;
2040
+
2041
+ generate_offset_from_harness ! (
2042
+ ( i8 , i8 ) ,
2043
+ check_const_offset_from_tuple_1,
2044
+ check_const_offset_from_tuple_1_arr
2045
+ ) ;
2046
+ generate_offset_from_harness ! (
2047
+ ( f64 , bool ) ,
2048
+ check_const_offset_from_tuple_2,
2049
+ check_const_offset_from_tuple_2_arr
2050
+ ) ;
2051
+ generate_offset_from_harness ! (
2052
+ ( u32 , i16 , f32 ) ,
2053
+ check_const_offset_from_tuple_3,
2054
+ check_const_offset_from_tuple_3_arr
2055
+ ) ;
2056
+ generate_offset_from_harness ! (
2057
+ ( ( ) , bool , u8 , u16 , i32 , f64 , i128 , usize ) ,
2058
+ check_const_offset_from_tuple_4,
2059
+ check_const_offset_from_tuple_4_arr
2060
+ ) ;
2061
+ }
0 commit comments