@@ -730,6 +730,16 @@ impl<T: ?Sized> *const T {
730730 #[ stable( feature = "pointer_byte_offsets" , since = "1.75.0" ) ]
731731 #[ rustc_const_stable( feature = "const_pointer_byte_offsets" , since = "1.75.0" ) ]
732732 #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
733+ #[ requires(
734+ ( mem:: size_of_val_raw( self ) != 0 ) &&
735+ // Ensures subtracting `origin` from `self` doesn't overflow
736+ ( self . addr( ) as isize ) . checked_sub( origin. addr( ) as isize ) . is_some( ) &&
737+ // Ensure both pointers are in the same allocation or are pointing to the same address
738+ ( self . addr( ) == origin. addr( ) ||
739+ core:: ub_checks:: same_allocation( self as * const u8 , origin as * const u8 ) )
740+ ) ]
741+ // The result should equal the distance in terms of bytes
742+ #[ ensures( |result| * result == ( self . addr( ) as isize - origin. addr( ) as isize ) ) ]
733743 pub const unsafe fn byte_offset_from < U : ?Sized > ( self , origin : * const U ) -> isize {
734744 // SAFETY: the caller must uphold the safety contract for `offset_from`.
735745 unsafe { self . cast :: < u8 > ( ) . offset_from ( origin. cast :: < u8 > ( ) ) }
@@ -1940,7 +1950,7 @@ mod verify {
19401950 check_const_offset_usize
19411951 ) ;
19421952
1943- // Generte harnesses for composite types (add, sub, offset)
1953+ // Generate harnesses for composite types (add, sub, offset)
19441954 generate_arithmetic_harnesses ! (
19451955 ( i8 , i8 ) ,
19461956 check_const_add_tuple_1,
@@ -2116,6 +2126,17 @@ mod verify {
21162126 // PointerGenerator does not support dynamic sized arrays.
21172127 const ARRAY_LEN : usize = 40 ;
21182128
2129+ #[ kani:: proof]
2130+ pub fn check_const_byte_offset_from_fixed_offset ( ) {
2131+ let arr: [ u32 ; ARRAY_LEN ] = kani:: Arbitrary :: any_array ( ) ;
2132+ let offset: usize = kani:: any_where ( |& x| x <= ARRAY_LEN ) ;
2133+ let origin_ptr: * const u32 = arr. as_ptr ( ) ;
2134+ let self_ptr: * const u32 = unsafe { origin_ptr. byte_offset ( offset as isize ) } ;
2135+ let result: isize = unsafe { self_ptr. byte_offset_from ( origin_ptr) } ;
2136+ assert_eq ! ( result, offset as isize ) ;
2137+ assert_eq ! ( result, ( self_ptr. addr( ) as isize - origin_ptr. addr( ) as isize ) ) ;
2138+ }
2139+
21192140 macro_rules! generate_offset_from_harness {
21202141 ( $type: ty, $proof_name1: ident, $proof_name2: ident) => {
21212142 // Proof for a single element
@@ -2156,7 +2177,7 @@ mod verify {
21562177 } ;
21572178 }
21582179
2159- // Proof for unit size will panic as offset_from needs the pointee size to be greater then 0
2180+ // Proof for unit size will panic as offset_from needs the pointee size to be greater than 0
21602181 #[ kani:: proof_for_contract( <* const ( ) >:: offset_from) ]
21612182 #[ kani:: should_panic]
21622183 pub fn check_const_offset_from_unit ( ) {
@@ -2252,6 +2273,186 @@ mod verify {
22522273 check_const_offset_from_tuple_4_arr
22532274 ) ;
22542275
2276+ // Proof for contact of byte_offset_from to verify unit type
2277+ #[ kani:: proof_for_contract( <* const ( ) >:: byte_offset_from) ]
2278+ pub fn check_const_byte_offset_from_unit ( ) {
2279+ let val: ( ) = ( ) ;
2280+ let src_ptr: * const ( ) = & val;
2281+ let dest_ptr: * const ( ) = & val;
2282+ unsafe {
2283+ dest_ptr. byte_offset_from ( src_ptr) ;
2284+ }
2285+ }
2286+
2287+ // generate proofs for contracts for byte_offset_from to verify int and composite
2288+ // types
2289+ // - `$type`: pointee type
2290+ // - `$proof_name1`: name of the harness for single element
2291+ // - `$proof_name2`: name of the harness for array of elements
2292+ macro_rules! generate_const_byte_offset_from_harness {
2293+ ( $type: ty, $proof_name1: ident, $proof_name2: ident) => {
2294+ // Proof for a single element
2295+ #[ kani:: proof_for_contract( <* const $type>:: byte_offset_from) ]
2296+ pub fn $proof_name1( ) {
2297+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
2298+ let mut generator1 = PointerGenerator :: <gen_size>:: new( ) ;
2299+ let mut generator2 = PointerGenerator :: <gen_size>:: new( ) ;
2300+ let ptr1: * const $type = generator1. any_in_bounds( ) . ptr;
2301+ let ptr2: * const $type = if kani:: any( ) {
2302+ generator1. any_alloc_status( ) . ptr
2303+ } else {
2304+ generator2. any_alloc_status( ) . ptr
2305+ } ;
2306+
2307+ unsafe {
2308+ ptr1. byte_offset_from( ptr2) ;
2309+ }
2310+ }
2311+
2312+ // Proof for large arrays
2313+ #[ kani:: proof_for_contract( <* const $type>:: byte_offset_from) ]
2314+ pub fn $proof_name2( ) {
2315+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
2316+ let mut generator1 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
2317+ let mut generator2 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
2318+ let ptr1: * const $type = generator1. any_in_bounds( ) . ptr;
2319+ let ptr2: * const $type = if kani:: any( ) {
2320+ generator1. any_alloc_status( ) . ptr
2321+ } else {
2322+ generator2. any_alloc_status( ) . ptr
2323+ } ;
2324+
2325+ unsafe {
2326+ ptr1. byte_offset_from( ptr2) ;
2327+ }
2328+ }
2329+ } ;
2330+ }
2331+
2332+ generate_const_byte_offset_from_harness ! (
2333+ u8 ,
2334+ check_const_byte_offset_from_u8,
2335+ check_const_byte_offset_from_u8_arr
2336+ ) ;
2337+ generate_const_byte_offset_from_harness ! (
2338+ u16 ,
2339+ check_const_byte_offset_from_u16,
2340+ check_const_byte_offset_from_u16_arr
2341+ ) ;
2342+ generate_const_byte_offset_from_harness ! (
2343+ u32 ,
2344+ check_const_byte_offset_from_u32,
2345+ check_const_byte_offset_from_u32_arr
2346+ ) ;
2347+ generate_const_byte_offset_from_harness ! (
2348+ u64 ,
2349+ check_const_byte_offset_from_u64,
2350+ check_const_byte_offset_from_u64_arr
2351+ ) ;
2352+ generate_const_byte_offset_from_harness ! (
2353+ u128 ,
2354+ check_const_byte_offset_from_u128,
2355+ check_const_byte_offset_from_u128_arr
2356+ ) ;
2357+ generate_const_byte_offset_from_harness ! (
2358+ usize ,
2359+ check_const_byte_offset_from_usize,
2360+ check_const_byte_offset_from_usize_arr
2361+ ) ;
2362+
2363+ generate_const_byte_offset_from_harness ! (
2364+ i8 ,
2365+ check_const_byte_offset_from_i8,
2366+ check_const_byte_offset_from_i8_arr
2367+ ) ;
2368+ generate_const_byte_offset_from_harness ! (
2369+ i16 ,
2370+ check_const_byte_offset_from_i16,
2371+ check_const_byte_offset_from_i16_arr
2372+ ) ;
2373+ generate_const_byte_offset_from_harness ! (
2374+ i32 ,
2375+ check_const_byte_offset_from_i32,
2376+ check_const_byte_offset_from_i32_arr
2377+ ) ;
2378+ generate_const_byte_offset_from_harness ! (
2379+ i64 ,
2380+ check_const_byte_offset_from_i64,
2381+ check_const_byte_offset_from_i64_arr
2382+ ) ;
2383+ generate_const_byte_offset_from_harness ! (
2384+ i128 ,
2385+ check_const_byte_offset_from_i128,
2386+ check_const_byte_offset_from_i128_arr
2387+ ) ;
2388+ generate_const_byte_offset_from_harness ! (
2389+ isize ,
2390+ check_const_byte_offset_from_isize,
2391+ check_const_byte_offset_from_isize_arr
2392+ ) ;
2393+
2394+ generate_const_byte_offset_from_harness ! (
2395+ ( i8 , i8 ) ,
2396+ check_const_byte_offset_from_tuple_1,
2397+ check_const_byte_offset_from_tuple_1_arr
2398+ ) ;
2399+ generate_const_byte_offset_from_harness ! (
2400+ ( f64 , bool ) ,
2401+ check_const_byte_offset_from_tuple_2,
2402+ check_const_byte_offset_from_tuple_2_arr
2403+ ) ;
2404+ generate_const_byte_offset_from_harness ! (
2405+ ( u32 , i16 , f32 ) ,
2406+ check_const_byte_offset_from_tuple_3,
2407+ check_const_byte_offset_from_tuple_3_arr
2408+ ) ;
2409+ generate_const_byte_offset_from_harness ! (
2410+ ( ( ) , bool , u8 , u16 , i32 , f64 , i128 , usize ) ,
2411+ check_const_byte_offset_from_tuple_4,
2412+ check_const_byte_offset_from_tuple_4_arr
2413+ ) ;
2414+
2415+ // length of the slice generated from PointerGenerator
2416+ const SLICE_LEN : usize = 10 ;
2417+
2418+ // generate proofs for contracts for byte_offset_from to verify slices
2419+ // - `$type`: type of the underlyign element within the slice pointer
2420+ // - `$proof_name`: name of the harness
2421+ macro_rules! generate_const_byte_offset_from_slice_harness {
2422+ ( $type: ty, $proof_name: ident) => {
2423+ #[ kani:: proof_for_contract( <* const [ $type] >:: byte_offset_from) ]
2424+ pub fn $proof_name( ) {
2425+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
2426+ let mut generator1 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
2427+ let mut generator2 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
2428+ let ptr1: * const [ $type] =
2429+ generator1. any_in_bounds( ) . ptr as * const [ $type; SLICE_LEN ] ;
2430+ let ptr2: * const [ $type] = if kani:: any( ) {
2431+ generator1. any_alloc_status( ) . ptr as * const [ $type; SLICE_LEN ]
2432+ } else {
2433+ generator2. any_alloc_status( ) . ptr as * const [ $type; SLICE_LEN ]
2434+ } ;
2435+
2436+ unsafe {
2437+ ptr1. byte_offset_from( ptr2) ;
2438+ }
2439+ }
2440+ } ;
2441+ }
2442+
2443+ generate_const_byte_offset_from_slice_harness ! ( u8 , check_const_byte_offset_from_u8_slice) ;
2444+ generate_const_byte_offset_from_slice_harness ! ( u16 , check_const_byte_offset_from_u16_slice) ;
2445+ generate_const_byte_offset_from_slice_harness ! ( u32 , check_const_byte_offset_from_u32_slice) ;
2446+ generate_const_byte_offset_from_slice_harness ! ( u64 , check_const_byte_offset_from_u64_slice) ;
2447+ generate_const_byte_offset_from_slice_harness ! ( u128 , check_const_byte_offset_from_u128_slice) ;
2448+ generate_const_byte_offset_from_slice_harness ! ( usize , check_const_byte_offset_from_usize_slice) ;
2449+ generate_const_byte_offset_from_slice_harness ! ( i8 , check_const_byte_offset_from_i8_slice) ;
2450+ generate_const_byte_offset_from_slice_harness ! ( i16 , check_const_byte_offset_from_i16_slice) ;
2451+ generate_const_byte_offset_from_slice_harness ! ( i32 , check_const_byte_offset_from_i32_slice) ;
2452+ generate_const_byte_offset_from_slice_harness ! ( i64 , check_const_byte_offset_from_i64_slice) ;
2453+ generate_const_byte_offset_from_slice_harness ! ( i128 , check_const_byte_offset_from_i128_slice) ;
2454+ generate_const_byte_offset_from_slice_harness ! ( isize , check_const_byte_offset_from_isize_slice) ;
2455+
22552456 #[ kani:: proof_for_contract( <* const ( ) >:: byte_offset) ]
22562457 #[ kani:: should_panic]
22572458 pub fn check_const_byte_offset_unit_invalid_count ( ) {
0 commit comments