@@ -730,6 +730,16 @@ impl<T: ?Sized> *const T {
730
730
#[ stable( feature = "pointer_byte_offsets" , since = "1.75.0" ) ]
731
731
#[ rustc_const_stable( feature = "const_pointer_byte_offsets" , since = "1.75.0" ) ]
732
732
#[ 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 ) ) ]
733
743
pub const unsafe fn byte_offset_from < U : ?Sized > ( self , origin : * const U ) -> isize {
734
744
// SAFETY: the caller must uphold the safety contract for `offset_from`.
735
745
unsafe { self . cast :: < u8 > ( ) . offset_from ( origin. cast :: < u8 > ( ) ) }
@@ -1940,7 +1950,7 @@ mod verify {
1940
1950
check_const_offset_usize
1941
1951
) ;
1942
1952
1943
- // Generte harnesses for composite types (add, sub, offset)
1953
+ // Generate harnesses for composite types (add, sub, offset)
1944
1954
generate_arithmetic_harnesses ! (
1945
1955
( i8 , i8 ) ,
1946
1956
check_const_add_tuple_1,
@@ -2116,6 +2126,17 @@ mod verify {
2116
2126
// PointerGenerator does not support dynamic sized arrays.
2117
2127
const ARRAY_LEN : usize = 40 ;
2118
2128
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
+
2119
2140
macro_rules! generate_offset_from_harness {
2120
2141
( $type: ty, $proof_name1: ident, $proof_name2: ident) => {
2121
2142
// Proof for a single element
@@ -2156,7 +2177,7 @@ mod verify {
2156
2177
} ;
2157
2178
}
2158
2179
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
2160
2181
#[ kani:: proof_for_contract( <* const ( ) >:: offset_from) ]
2161
2182
#[ kani:: should_panic]
2162
2183
pub fn check_const_offset_from_unit ( ) {
@@ -2252,6 +2273,186 @@ mod verify {
2252
2273
check_const_offset_from_tuple_4_arr
2253
2274
) ;
2254
2275
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
+
2255
2456
#[ kani:: proof_for_contract( <* const ( ) >:: byte_offset) ]
2256
2457
#[ kani:: should_panic]
2257
2458
pub fn check_const_byte_offset_unit_invalid_count ( ) {
0 commit comments