@@ -405,10 +405,11 @@ impl<T: ?Sized> *mut T {
405
405
// Note: It is the caller's responsibility to ensure that `self` is non-null and properly aligned.
406
406
// These conditions are not verified as part of the preconditions.
407
407
#[ requires(
408
- // Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`
409
- count. checked_mul( core:: mem:: size_of:: <T >( ) as isize ) . is_some( ) &&
410
- // Precondition 2: adding the computed offset to `self` does not cause overflow
411
- ( self as isize ) . checked_add( ( count * core:: mem:: size_of:: <T >( ) as isize ) ) . is_some( ) &&
408
+ // Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`.
409
+ // Precondition 2: adding the computed offset to `self` does not cause overflow.
410
+ // These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
411
+ count. checked_mul( core:: mem:: size_of:: <T >( ) as isize )
412
+ . map_or( false , |computed_offset| ( self as isize ) . checked_add( computed_offset) . is_some( ) ) &&
412
413
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
413
414
// Otherwise, for non-unit types, `self` and `self.wrapping_offset(count)` should point to the same allocated object,
414
415
// restricting `count` to prevent crossing allocation boundaries.
@@ -1016,11 +1017,13 @@ impl<T: ?Sized> *mut T {
1016
1017
// Note: It is the caller's responsibility to ensure that `self` is non-null and properly aligned.
1017
1018
// These conditions are not verified as part of the preconditions.
1018
1019
#[ requires(
1019
- // Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`
1020
- count. checked_mul( core:: mem:: size_of:: <T >( ) ) . is_some( ) &&
1021
- count * core:: mem:: size_of:: <T >( ) <= isize :: MAX as usize &&
1022
- // Precondition 2: adding the computed offset to `self` does not cause overflow
1023
- ( self as isize ) . checked_add( ( count * core:: mem:: size_of:: <T >( ) ) as isize ) . is_some( ) &&
1020
+ // Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`.
1021
+ // Precondition 2: adding the computed offset to `self` does not cause overflow.
1022
+ // These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
1023
+ count. checked_mul( core:: mem:: size_of:: <T >( ) )
1024
+ . map_or( false , |computed_offset| {
1025
+ computed_offset <= isize :: MAX as usize && ( self as isize ) . checked_add( computed_offset as isize ) . is_some( )
1026
+ } ) &&
1024
1027
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
1025
1028
// Otherwise, for non-unit types, `self` and `self.wrapping_add(count)` should point to the same allocated object,
1026
1029
// restricting `count` to prevent crossing allocation boundaries.
@@ -1140,11 +1143,13 @@ impl<T: ?Sized> *mut T {
1140
1143
// Note: It is the caller's responsibility to ensure that `self` is non-null and properly aligned.
1141
1144
// These conditions are not verified as part of the preconditions.
1142
1145
#[ requires(
1143
- // Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`
1144
- count. checked_mul( core:: mem:: size_of:: <T >( ) ) . is_some( ) &&
1145
- count * core:: mem:: size_of:: <T >( ) <= isize :: MAX as usize &&
1146
- // Precondition 2: subtracting the computed offset from `self` does not cause overflow
1147
- ( self as isize ) . checked_sub( ( count * core:: mem:: size_of:: <T >( ) ) as isize ) . is_some( ) &&
1146
+ // Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`.
1147
+ // Precondition 2: substracting the computed offset from `self` does not cause overflow.
1148
+ // These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
1149
+ count. checked_mul( core:: mem:: size_of:: <T >( ) )
1150
+ . map_or( false , |computed_offset| {
1151
+ computed_offset <= isize :: MAX as usize && ( self as isize ) . checked_sub( computed_offset as isize ) . is_some( )
1152
+ } ) &&
1148
1153
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
1149
1154
// Otherwise, for non-unit types, `self` and `self.wrapping_sub(count)` should point to the same allocated object,
1150
1155
// restricting `count` to prevent crossing allocation boundaries.
@@ -2173,120 +2178,143 @@ impl<T: ?Sized> PartialOrd for *mut T {
2173
2178
mod verify {
2174
2179
use crate :: kani;
2175
2180
2176
- /// This macro generates proofs for contracts on `add`, `sub`, and `offset`
2177
- /// operations for pointers to integer, composite, and unit types.
2178
- /// - `$type`: Specifies the pointee type.
2179
- /// - `$proof_name`: Specifies the name of the generated proof for contract.
2180
- macro_rules! generate_mut_arithmetic_harness {
2181
- ( $type: ty, $proof_name: ident, add) => {
2182
- #[ kani:: proof_for_contract( <* mut $type>:: add) ]
2181
+ /// This macro generates a single verification harness for the `offset`, `add`, or `sub`
2182
+ /// pointer operations, supporting integer, composite, or unit types.
2183
+ /// - `$ty`: The type of the slice's elements (e.g., `i32`, `u32`, tuples).
2184
+ /// - `$fn_name`: The name of the function being checked (`add`, `sub`, or `offset`).
2185
+ /// - `$proof_name`: The name assigned to the generated proof for the contract.
2186
+ /// - `$count_ty:ty`: The type of the input variable passed to the method being invoked.
2187
+ ///
2188
+ /// Note: This macro is intended for internal use only and should be invoked exclusively
2189
+ /// by the `generate_arithmetic_harnesses` macro. Its purpose is to reduce code duplication,
2190
+ /// and it is not meant to be used directly elsewhere in the codebase.
2191
+ macro_rules! generate_single_arithmetic_harness {
2192
+ ( $ty: ty, $proof_name: ident, $fn_name: ident, $count_ty: ty) => {
2193
+ #[ kani:: proof_for_contract( <* mut $ty>:: $fn_name) ]
2183
2194
pub fn $proof_name( ) {
2184
2195
// 200 bytes are large enough to cover all pointee types used for testing
2185
2196
const BUF_SIZE : usize = 200 ;
2186
2197
let mut generator = kani:: PointerGenerator :: <BUF_SIZE >:: new( ) ;
2187
- let test_ptr: * mut $type = generator. any_in_bounds( ) . ptr;
2188
- let count: usize = kani:: any( ) ;
2198
+ let test_ptr: * mut $ty = generator. any_in_bounds( ) . ptr;
2199
+ let count: $count_ty = kani:: any( ) ;
2189
2200
unsafe {
2190
- test_ptr. add ( count) ;
2201
+ test_ptr. $fn_name ( count) ;
2191
2202
}
2192
2203
}
2193
2204
} ;
2194
- ( $type: ty, $proof_name: ident, sub) => {
2195
- #[ kani:: proof_for_contract( <* mut $type>:: sub) ]
2196
- pub fn $proof_name( ) {
2197
- // 200 bytes are large enough to cover all pointee types used for testing
2198
- const BUF_SIZE : usize = 200 ;
2199
- let mut generator = kani:: PointerGenerator :: <BUF_SIZE >:: new( ) ;
2200
- let test_ptr: * mut $type = generator. any_in_bounds( ) . ptr;
2201
- let count: usize = kani:: any( ) ;
2202
- unsafe {
2203
- test_ptr. sub( count) ;
2204
- }
2205
- }
2206
- } ;
2207
- ( $type: ty, $proof_name: ident, offset) => {
2208
- #[ kani:: proof_for_contract( <* mut $type>:: offset) ]
2209
- pub fn $proof_name( ) {
2210
- // 200 bytes are large enough to cover all pointee types used for testing
2211
- const BUF_SIZE : usize = 200 ;
2212
- let mut generator = kani:: PointerGenerator :: <BUF_SIZE >:: new( ) ;
2213
- let test_ptr: * mut $type = generator. any_in_bounds( ) . ptr;
2214
- let count: isize = kani:: any( ) ;
2215
- unsafe {
2216
- test_ptr. offset( count) ;
2217
- }
2218
- }
2205
+ }
2206
+
2207
+ /// This macro generates verification harnesses for the `offset`, `add`, and `sub`
2208
+ /// pointer operations, supporting integer, composite, and unit types.
2209
+ /// - `$ty`: The pointee type (e.g., i32, u32, tuples).
2210
+ /// - `$offset_fn_name`: The name for the `offset` proof for contract.
2211
+ /// - `$add_fn_name`: The name for the `add` proof for contract.
2212
+ /// - `$sub_fn_name`: The name for the `sub` proof for contract.
2213
+ macro_rules! generate_arithmetic_harnesses {
2214
+ ( $ty: ty, $add_fn_name: ident, $sub_fn_name: ident, $offset_fn_name: ident) => {
2215
+ generate_single_arithmetic_harness!( $ty, $add_fn_name, add, usize ) ;
2216
+ generate_single_arithmetic_harness!( $ty, $sub_fn_name, sub, usize ) ;
2217
+ generate_single_arithmetic_harness!( $ty, $offset_fn_name, offset, isize ) ;
2219
2218
} ;
2220
2219
}
2221
2220
2222
- // <*mut T>:: add() integer types verification
2223
- generate_mut_arithmetic_harness ! ( i8 , check_mut_add_i8, add) ;
2224
- generate_mut_arithmetic_harness ! ( i16 , check_mut_add_i16, add) ;
2225
- generate_mut_arithmetic_harness ! ( i32 , check_mut_add_i32, add) ;
2226
- generate_mut_arithmetic_harness ! ( i64 , check_mut_add_i64, add) ;
2227
- generate_mut_arithmetic_harness ! ( i128 , check_mut_add_i128, add) ;
2228
- generate_mut_arithmetic_harness ! ( isize , check_mut_add_isize, add) ;
2229
- // Due to a bug of kani this test case is malfunctioning for now.
2221
+ // Generate harnesses for unit type (add, sub, offset)
2222
+ generate_arithmetic_harnesses ! (
2223
+ ( ) ,
2224
+ check_mut_add_unit,
2225
+ check_mut_sub_unit,
2226
+ check_mut_offset_unit
2227
+ ) ;
2228
+
2229
+ // Generate harnesses for integer types (add, sub, offset)
2230
+ generate_arithmetic_harnesses ! ( i8 , check_mut_add_i8, check_mut_sub_i8, check_mut_offset_i8) ;
2231
+ generate_arithmetic_harnesses ! (
2232
+ i16 ,
2233
+ check_mut_add_i16,
2234
+ check_mut_sub_i16,
2235
+ check_mut_offset_i16
2236
+ ) ;
2237
+ generate_arithmetic_harnesses ! (
2238
+ i32 ,
2239
+ check_mut_add_i32,
2240
+ check_mut_sub_i32,
2241
+ check_mut_offset_i32
2242
+ ) ;
2243
+ generate_arithmetic_harnesses ! (
2244
+ i64 ,
2245
+ check_mut_add_i64,
2246
+ check_mut_sub_i64,
2247
+ check_mut_offset_i64
2248
+ ) ;
2249
+ generate_arithmetic_harnesses ! (
2250
+ i128 ,
2251
+ check_mut_add_i128,
2252
+ check_mut_sub_i128,
2253
+ check_mut_offset_i128
2254
+ ) ;
2255
+ generate_arithmetic_harnesses ! (
2256
+ isize ,
2257
+ check_mut_add_isize,
2258
+ check_mut_sub_isize,
2259
+ check_mut_offset_isize
2260
+ ) ;
2261
+ // Due to a bug of kani the test `check_mut_add_u8` is malfunctioning for now.
2230
2262
// Tracking issue: https://github.com/model-checking/kani/issues/3743
2231
- // generate_mut_arithmetic_harness!(u8, check_mut_add_u8, add);
2232
- generate_mut_arithmetic_harness ! ( u16 , check_mut_add_u16, add) ;
2233
- generate_mut_arithmetic_harness ! ( u32 , check_mut_add_u32, add) ;
2234
- generate_mut_arithmetic_harness ! ( u64 , check_mut_add_u64, add) ;
2235
- generate_mut_arithmetic_harness ! ( u128 , check_mut_add_u128, add) ;
2236
- generate_mut_arithmetic_harness ! ( usize , check_mut_add_usize, add) ;
2237
-
2238
- // <*mut T>:: add() unit type verification
2239
- generate_mut_arithmetic_harness ! ( ( ) , check_mut_add_unit, add) ;
2240
-
2241
- // <*mut T>:: add() composite types verification
2242
- generate_mut_arithmetic_harness ! ( ( i8 , i8 ) , check_mut_add_tuple_1, add) ;
2243
- generate_mut_arithmetic_harness ! ( ( f64 , bool ) , check_mut_add_tuple_2, add) ;
2244
- generate_mut_arithmetic_harness ! ( ( i32 , f64 , bool ) , check_mut_add_tuple_3, add) ;
2245
- generate_mut_arithmetic_harness ! ( ( i8 , u16 , i32 , u64 , isize ) , check_mut_add_tuple_4, add) ;
2246
-
2247
- // <*mut T>:: sub() integer types verification
2248
- generate_mut_arithmetic_harness ! ( i8 , check_mut_sub_i8, sub) ;
2249
- generate_mut_arithmetic_harness ! ( i16 , check_mut_sub_i16, sub) ;
2250
- generate_mut_arithmetic_harness ! ( i32 , check_mut_sub_i32, sub) ;
2251
- generate_mut_arithmetic_harness ! ( i64 , check_mut_sub_i64, sub) ;
2252
- generate_mut_arithmetic_harness ! ( i128 , check_mut_sub_i128, sub) ;
2253
- generate_mut_arithmetic_harness ! ( isize , check_mut_sub_isize, sub) ;
2254
- generate_mut_arithmetic_harness ! ( u8 , check_mut_sub_u8, sub) ;
2255
- generate_mut_arithmetic_harness ! ( u16 , check_mut_sub_u16, sub) ;
2256
- generate_mut_arithmetic_harness ! ( u32 , check_mut_sub_u32, sub) ;
2257
- generate_mut_arithmetic_harness ! ( u64 , check_mut_sub_u64, sub) ;
2258
- generate_mut_arithmetic_harness ! ( u128 , check_mut_sub_u128, sub) ;
2259
- generate_mut_arithmetic_harness ! ( usize , check_mut_sub_usize, sub) ;
2260
-
2261
- // <*mut T>:: sub() unit type verification
2262
- generate_mut_arithmetic_harness ! ( ( ) , check_mut_sub_unit, sub) ;
2263
-
2264
- // <*mut T>:: sub() composite types verification
2265
- generate_mut_arithmetic_harness ! ( ( i8 , i8 ) , check_mut_sub_tuple_1, sub) ;
2266
- generate_mut_arithmetic_harness ! ( ( f64 , bool ) , check_mut_sub_tuple_2, sub) ;
2267
- generate_mut_arithmetic_harness ! ( ( i32 , f64 , bool ) , check_mut_sub_tuple_3, sub) ;
2268
- generate_mut_arithmetic_harness ! ( ( i8 , u16 , i32 , u64 , isize ) , check_mut_sub_tuple_4, sub) ;
2269
-
2270
- // fn <*mut T>::offset() integer types verification
2271
- generate_mut_arithmetic_harness ! ( i8 , check_mut_offset_i8, offset) ;
2272
- generate_mut_arithmetic_harness ! ( i16 , check_mut_offset_i16, offset) ;
2273
- generate_mut_arithmetic_harness ! ( i32 , check_mut_offset_i32, offset) ;
2274
- generate_mut_arithmetic_harness ! ( i64 , check_mut_offset_i64, offset) ;
2275
- generate_mut_arithmetic_harness ! ( i128 , check_mut_offset_i128, offset) ;
2276
- generate_mut_arithmetic_harness ! ( isize , check_mut_offset_isize, offset) ;
2277
- generate_mut_arithmetic_harness ! ( u8 , check_mut_offset_u8, offset) ;
2278
- generate_mut_arithmetic_harness ! ( u16 , check_mut_offset_u16, offset) ;
2279
- generate_mut_arithmetic_harness ! ( u32 , check_mut_offset_u32, offset) ;
2280
- generate_mut_arithmetic_harness ! ( u64 , check_mut_offset_u64, offset) ;
2281
- generate_mut_arithmetic_harness ! ( u128 , check_mut_offset_u128, offset) ;
2282
- generate_mut_arithmetic_harness ! ( usize , check_mut_offset_usize, offset) ;
2283
-
2284
- // fn <*mut T>::offset() unit type verification
2285
- generate_mut_arithmetic_harness ! ( ( ) , check_mut_offset_unit, offset) ;
2286
-
2287
- // fn <*mut T>::offset() composite type verification
2288
- generate_mut_arithmetic_harness ! ( ( i8 , i8 ) , check_mut_offset_tuple_1, offset) ;
2289
- generate_mut_arithmetic_harness ! ( ( f64 , bool ) , check_mut_offset_tuple_2, offset) ;
2290
- generate_mut_arithmetic_harness ! ( ( i32 , f64 , bool ) , check_mut_offset_tuple_3, offset) ;
2291
- generate_mut_arithmetic_harness ! ( ( i8 , u16 , i32 , u64 , isize ) , check_mut_offset_tuple_4, offset) ;
2263
+ // generate_arithmetic_harnesses!(u8, check_mut_add_u8, check_mut_sub_u8, check_mut_offset_u8);
2264
+ generate_arithmetic_harnesses ! (
2265
+ u16 ,
2266
+ check_mut_add_u16,
2267
+ check_mut_sub_u16,
2268
+ check_mut_offset_u16
2269
+ ) ;
2270
+ generate_arithmetic_harnesses ! (
2271
+ u32 ,
2272
+ check_mut_add_u32,
2273
+ check_mut_sub_u32,
2274
+ check_mut_offset_u32
2275
+ ) ;
2276
+ generate_arithmetic_harnesses ! (
2277
+ u64 ,
2278
+ check_mut_add_u64,
2279
+ check_mut_sub_u64,
2280
+ check_mut_offset_u64
2281
+ ) ;
2282
+ generate_arithmetic_harnesses ! (
2283
+ u128 ,
2284
+ check_mut_add_u128,
2285
+ check_mut_sub_u128,
2286
+ check_mut_offset_u128
2287
+ ) ;
2288
+ generate_arithmetic_harnesses ! (
2289
+ usize ,
2290
+ check_mut_add_usize,
2291
+ check_mut_sub_usize,
2292
+ check_mut_offset_usize
2293
+ ) ;
2294
+
2295
+ // Generte harnesses for composite types (add, sub, offset)
2296
+ generate_arithmetic_harnesses ! (
2297
+ ( i8 , i8 ) ,
2298
+ check_mut_add_tuple_1,
2299
+ check_mut_sub_tuple_1,
2300
+ check_mut_offset_tuple_1
2301
+ ) ;
2302
+ generate_arithmetic_harnesses ! (
2303
+ ( f64 , bool ) ,
2304
+ check_mut_add_tuple_2,
2305
+ check_mut_sub_tuple_2,
2306
+ check_mut_offset_tuple_2
2307
+ ) ;
2308
+ generate_arithmetic_harnesses ! (
2309
+ ( i32 , f64 , bool ) ,
2310
+ check_mut_add_tuple_3,
2311
+ check_mut_sub_tuple_3,
2312
+ check_mut_offset_tuple_3
2313
+ ) ;
2314
+ generate_arithmetic_harnesses ! (
2315
+ ( i8 , u16 , i32 , u64 , isize ) ,
2316
+ check_mut_add_tuple_4,
2317
+ check_mut_sub_tuple_4,
2318
+ check_mut_offset_tuple_4
2319
+ ) ;
2292
2320
}
0 commit comments