@@ -857,11 +857,22 @@ impl<T: ?Sized> *mut T {
857857 /// unsafe {
858858 /// let one = ptr2_other.offset_from(ptr2); // Undefined Behavior! ⚠️
859859 /// }
860+ ///
861+ ///
860862 /// ```
861863 #[ stable( feature = "ptr_offset_from" , since = "1.47.0" ) ]
862864 #[ rustc_const_stable( feature = "const_ptr_offset_from" , since = "1.65.0" ) ]
863865 #[ inline( always) ]
864866 #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
867+ #[ requires(
868+ // Ensuring that subtracting 'origin' from 'self' doesn't result in an overflow
869+ ( self as isize ) . checked_sub( origin as isize ) . is_some( ) &&
870+ // Ensuring that the distance between 'self' and 'origin' is aligned to `T`
871+ ( self as isize - origin as isize ) % ( mem:: size_of:: <T >( ) as isize ) == 0 &&
872+ // Ensuring that both pointers point to the same address or are in the same allocation
873+ ( self as isize == origin as isize || core:: ub_checks:: same_allocation( self , origin) )
874+ ) ]
875+ #[ ensures( |result| * result == ( self as isize - origin as isize ) / ( mem:: size_of:: <T >( ) as isize ) ) ]
865876 pub const unsafe fn offset_from ( self , origin : * const T ) -> isize
866877 where
867878 T : Sized ,
@@ -2472,143 +2483,79 @@ mod verify {
24722483 gen_mut_byte_arith_harness_for_slice ! ( u128 , byte_offset, check_mut_byte_offset_u128_slice) ;
24732484 gen_mut_byte_arith_harness_for_slice ! ( usize , byte_offset, check_mut_byte_offset_usize_slice) ;
24742485
2475- /// This macro generates a single verification harness for the `offset`, `add`, or `sub`
2476- /// pointer operations, supporting integer, composite, or unit types.
2477- /// - `$ty`: The type of the slice's elements (e.g., `i32`, `u32`, tuples).
2478- /// - `$fn_name`: The name of the function being checked (`add`, `sub`, or `offset`).
2479- /// - `$proof_name`: The name assigned to the generated proof for the contract.
2480- /// - `$count_ty:ty`: The type of the input variable passed to the method being invoked.
2481- ///
2482- /// Note: This macro is intended for internal use only and should be invoked exclusively
2483- /// by the `generate_arithmetic_harnesses` macro. Its purpose is to reduce code duplication,
2484- /// and it is not meant to be used directly elsewhere in the codebase.
2485- macro_rules! generate_single_arithmetic_harness {
2486- ( $ty: ty, $proof_name: ident, $fn_name: ident, $count_ty: ty) => {
2487- #[ kani:: proof_for_contract( <* mut $ty>:: $fn_name) ]
2488- pub fn $proof_name( ) {
2489- // 200 bytes are large enough to cover all pointee types used for testing
2490- const BUF_SIZE : usize = 200 ;
2491- let mut generator = kani:: PointerGenerator :: <BUF_SIZE >:: new( ) ;
2492- let test_ptr: * mut $ty = generator. any_in_bounds( ) . ptr;
2493- let count: $count_ty = kani:: any( ) ;
2486+ // The proof for a unit type panics as offset_from needs the pointee size > 0
2487+ #[ kani:: proof_for_contract( <* mut ( ) >:: offset_from) ]
2488+ #[ kani:: should_panic]
2489+ pub fn check_mut_offset_from_unit ( ) {
2490+ let mut val: ( ) = ( ) ;
2491+ let src_ptr: * mut ( ) = & mut val;
2492+ let dest_ptr: * mut ( ) = & mut val;
2493+ unsafe {
2494+ dest_ptr. offset_from ( src_ptr) ;
2495+ }
2496+ }
2497+
2498+ macro_rules! generate_offset_from_harness {
2499+ ( $type: ty, $proof_name1: ident, $proof_name2: ident) => {
2500+ #[ kani:: proof_for_contract( <* mut $type>:: offset_from) ]
2501+ // Below function is for a single element
2502+ pub fn $proof_name1( ) {
2503+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
2504+ let mut generator1 = PointerGenerator :: <gen_size>:: new( ) ;
2505+ let mut generator2 = PointerGenerator :: <gen_size>:: new( ) ;
2506+ let ptr1: * mut $type = generator1. any_in_bounds( ) . ptr;
2507+ let ptr2: * mut $type = if kani:: any( ) {
2508+ generator1. any_alloc_status( ) . ptr
2509+ } else {
2510+ generator2. any_alloc_status( ) . ptr
2511+ } ;
2512+
24942513 unsafe {
2495- test_ptr. $fn_name( count) ;
2514+ ptr1. offset_from( ptr2) ;
2515+ }
2516+ }
2517+
2518+ // Below function is for large arrays
2519+ pub fn $proof_name2( ) {
2520+ const gen_size: usize = mem:: size_of:: <$type>( ) ;
2521+ let mut generator1 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
2522+ let mut generator2 = PointerGenerator :: <{ gen_size * ARRAY_LEN } >:: new( ) ;
2523+ let ptr1: * mut $type = generator1. any_in_bounds( ) . ptr;
2524+ let ptr2: * mut $type = if kani:: any( ) {
2525+ generator1. any_alloc_status( ) . ptr
2526+ } else {
2527+ generator2. any_alloc_status( ) . ptr
2528+ } ;
2529+
2530+ unsafe {
2531+ ptr1. offset_from( ptr2) ;
24962532 }
24972533 }
2498- } ;
2499- }
25002534
2501- /// This macro generates verification harnesses for the `offset`, `add`, and `sub`
2502- /// pointer operations, supporting integer, composite, and unit types.
2503- /// - `$ty`: The pointee type (e.g., i32, u32, tuples).
2504- /// - `$offset_fn_name`: The name for the `offset` proof for contract.
2505- /// - `$add_fn_name`: The name for the `add` proof for contract.
2506- /// - `$sub_fn_name`: The name for the `sub` proof for contract.
2507- macro_rules! generate_arithmetic_harnesses {
2508- ( $ty: ty, $add_fn_name: ident, $sub_fn_name: ident, $offset_fn_name: ident) => {
2509- generate_single_arithmetic_harness!( $ty, $add_fn_name, add, usize ) ;
2510- generate_single_arithmetic_harness!( $ty, $sub_fn_name, sub, usize ) ;
2511- generate_single_arithmetic_harness!( $ty, $offset_fn_name, offset, isize ) ;
25122535 } ;
25132536 }
25142537
2515- // Generate harnesses for unit type (add, sub, offset)
2516- generate_arithmetic_harnesses ! (
2517- ( ) ,
2518- check_mut_add_unit,
2519- check_mut_sub_unit,
2520- check_mut_offset_unit
2521- ) ;
2522-
2523- // Generate harnesses for integer types (add, sub, offset)
2524- generate_arithmetic_harnesses ! ( i8 , check_mut_add_i8, check_mut_sub_i8, check_mut_offset_i8) ;
2525- generate_arithmetic_harnesses ! (
2526- i16 ,
2527- check_mut_add_i16,
2528- check_mut_sub_i16,
2529- check_mut_offset_i16
2530- ) ;
2531- generate_arithmetic_harnesses ! (
2532- i32 ,
2533- check_mut_add_i32,
2534- check_mut_sub_i32,
2535- check_mut_offset_i32
2536- ) ;
2537- generate_arithmetic_harnesses ! (
2538- i64 ,
2539- check_mut_add_i64,
2540- check_mut_sub_i64,
2541- check_mut_offset_i64
2542- ) ;
2543- generate_arithmetic_harnesses ! (
2544- i128 ,
2545- check_mut_add_i128,
2546- check_mut_sub_i128,
2547- check_mut_offset_i128
2548- ) ;
2549- generate_arithmetic_harnesses ! (
2550- isize ,
2551- check_mut_add_isize,
2552- check_mut_sub_isize,
2553- check_mut_offset_isize
2554- ) ;
2555- // Due to a bug of kani the test `check_mut_add_u8` is malfunctioning for now.
2556- // Tracking issue: https://github.com/model-checking/kani/issues/3743
2557- // generate_arithmetic_harnesses!(u8, check_mut_add_u8, check_mut_sub_u8, check_mut_offset_u8);
2558- generate_arithmetic_harnesses ! (
2559- u16 ,
2560- check_mut_add_u16,
2561- check_mut_sub_u16,
2562- check_mut_offset_u16
2563- ) ;
2564- generate_arithmetic_harnesses ! (
2565- u32 ,
2566- check_mut_add_u32,
2567- check_mut_sub_u32,
2568- check_mut_offset_u32
2569- ) ;
2570- generate_arithmetic_harnesses ! (
2571- u64 ,
2572- check_mut_add_u64,
2573- check_mut_sub_u64,
2574- check_mut_offset_u64
2575- ) ;
2576- generate_arithmetic_harnesses ! (
2577- u128 ,
2578- check_mut_add_u128,
2579- check_mut_sub_u128,
2580- check_mut_offset_u128
2581- ) ;
2582- generate_arithmetic_harnesses ! (
2583- usize ,
2584- check_mut_add_usize,
2585- check_mut_sub_usize,
2586- check_mut_offset_usize
2538+ generate_offset_from_harness ! ( u8 , check_mut_offset_from_u8, check_mut_offset_from_u8_array) ;
2539+ generate_offset_from_harness ! ( u16 , check_mut_offset_from_u16, check_mut_offset_from_u16_array) ;
2540+ generate_offset_from_harness ! ( u32 , check_mut_offset_from_u32, check_mut_offset_from_u32_array) ;
2541+ generate_offset_from_harness ! ( u64 , check_mut_offset_from_u64, check_mut_offset_from_u64_array) ;
2542+ generate_offset_from_harness ! ( u128 , check_mut_offset_from_u128, check_mut_offset_from_u128_array) ;
2543+ generate_offset_from_harness ! ( usize , check_mut_offset_from_usize, check_mut_offset_from_usize_array) ;
2544+
2545+ generate_offset_from_harness ! ( i8 , check_mut_offset_from_i8, check_mut_offset_from_i8_array) ;
2546+ generate_offset_from_harness ! ( i16 , check_mut_offset_from_i16, check_mut_offset_from_i16_array) ;
2547+ generate_offset_from_harness ! ( i32 , check_mut_offset_from_i32, check_mut_offset_from_i32_array) ;
2548+ generate_offset_from_harness ! ( i64 , check_mut_offset_from_i64, check_mut_offset_from_i64_array) ;
2549+ generate_offset_from_harness ! ( i128 , check_mut_offset_from_i128, check_mut_offset_from_i128_array) ;
2550+ generate_offset_from_harness ! ( isize , check_mut_offset_from_isize, check_mut_offset_from_isize_array) ;
2551+
2552+ generate_offset_from_harness ! ( ( i8 , i8 ) , check_mut_offset_from_tuple_1, check_mut_offset_from_tuple_1_array) ;
2553+ generate_offset_from_harness ! ( ( f64 , bool ) , check_mut_offset_from_tuple_2, check_mut_offset_from_tuple_2_array) ;
2554+ generate_offset_from_harness ! ( ( u32 , i16 , f32 ) , check_mut_offset_from_tuple_3, check_mut_offset_from_tuple_3_array) ;
2555+ generate_offset_from_harness ! (
2556+ ( ( ) , bool , u8 , u16 , i32 , f64 , i128 , usize ) ,
2557+ check_mut_offset_from_tuple_4,
2558+ check_mut_offset_from_tuple_4_array
25872559 ) ;
25882560
2589- // Generte harnesses for composite types (add, sub, offset)
2590- generate_arithmetic_harnesses ! (
2591- ( i8 , i8 ) ,
2592- check_mut_add_tuple_1,
2593- check_mut_sub_tuple_1,
2594- check_mut_offset_tuple_1
2595- ) ;
2596- generate_arithmetic_harnesses ! (
2597- ( f64 , bool ) ,
2598- check_mut_add_tuple_2,
2599- check_mut_sub_tuple_2,
2600- check_mut_offset_tuple_2
2601- ) ;
2602- generate_arithmetic_harnesses ! (
2603- ( i32 , f64 , bool ) ,
2604- check_mut_add_tuple_3,
2605- check_mut_sub_tuple_3,
2606- check_mut_offset_tuple_3
2607- ) ;
2608- generate_arithmetic_harnesses ! (
2609- ( i8 , u16 , i32 , u64 , isize ) ,
2610- check_mut_add_tuple_4,
2611- check_mut_sub_tuple_4,
2612- check_mut_offset_tuple_4
2613- ) ;
26142561}
0 commit comments