Skip to content

Commit a636c05

Browse files
MWDZYenyun035
andauthored
Contracts & Harnesses for wrapping_shr (rust-lang#123)
Towards model-checking#59 Changes Added contracts for wrapping_shr (located in library/core/src/num/int_macros.rs and uint_macros.rs) Added harnesses for wrapping_shr of each integer type i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize --- 12 harnesses in total. Revalidation Per the discussion in model-checking#59, we have to build and run Kani from feature/verify-rust-std branch. To revalidate the verification results, run the following command. <harness_to_run> can be either num::verify to run all harnesses or num::verify::<harness_name> (e.g. checked_wrapping_shl_i8) to run a specific harness. ``` kani verify-std "path/to/library" \ --harness <harness_to_run> \ -Z unstable-options \ -Z function-contracts \ -Z mem-predicates ``` All harnesses should pass the default checks (1251 checks where 1 unreachable). ``` SUMMARY: ** 0 of 161 failed (1 unreachable) VERIFICATION:- SUCCESSFUL Verification Time: 0.32086188s Complete - 12 successfully verified harnesses, 0 failures, 12 total. ``` Example of the unreachable check: ``` Check 9: num::<impl i8>::wrapping_shr.assertion.1 - Status: UNREACHABLE - Description: "attempt to subtract with overflow" - Location: library/core/src/num/int_macros.rs:2199:42 in function num::<impl i8>::wrapping_shr ``` --------- Co-authored-by: Yenyun035 <[email protected]>
1 parent 3a967e3 commit a636c05

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

library/core/src/num/int_macros.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,7 @@ macro_rules! int_impl {
21912191
without modifying the original"]
21922192
#[inline(always)]
21932193
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
2194+
#[ensures(|result| *result == self >> (rhs & (Self::BITS - 1)))]
21942195
pub const fn wrapping_shr(self, rhs: u32) -> Self {
21952196
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
21962197
// out of bounds

library/core/src/num/mod.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1943,4 +1943,28 @@ mod verify {
19431943
generate_wrapping_shift_harness!(u64, wrapping_shl, checked_wrapping_shl_u64);
19441944
generate_wrapping_shift_harness!(u128, wrapping_shl, checked_wrapping_shl_u128);
19451945
generate_wrapping_shift_harness!(usize, wrapping_shl, checked_wrapping_shl_usize);
1946+
1947+
// `wrapping_shr` proofs
1948+
//
1949+
// Target types:
1950+
// i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total
1951+
//
1952+
// Target contracts:
1953+
// #[ensures(|result| *result == self >> (rhs & (Self::BITS - 1)))]
1954+
// Target function:
1955+
// pub const fn wrapping_shr(self, rhs: u32) -> Self {
1956+
//
1957+
// This function performs an panic-free bitwise right shift operation.
1958+
generate_wrapping_shift_harness!(i8, wrapping_shr, checked_wrapping_shr_i8);
1959+
generate_wrapping_shift_harness!(i16, wrapping_shr, checked_wrapping_shr_i16);
1960+
generate_wrapping_shift_harness!(i32, wrapping_shr, checked_wrapping_shr_i32);
1961+
generate_wrapping_shift_harness!(i64, wrapping_shr, checked_wrapping_shr_i64);
1962+
generate_wrapping_shift_harness!(i128, wrapping_shr, checked_wrapping_shr_i128);
1963+
generate_wrapping_shift_harness!(isize, wrapping_shr, checked_wrapping_shr_isize);
1964+
generate_wrapping_shift_harness!(u8, wrapping_shr, checked_wrapping_shr_u8);
1965+
generate_wrapping_shift_harness!(u16, wrapping_shr, checked_wrapping_shr_u16);
1966+
generate_wrapping_shift_harness!(u32, wrapping_shr, checked_wrapping_shr_u32);
1967+
generate_wrapping_shift_harness!(u64, wrapping_shr, checked_wrapping_shr_u64);
1968+
generate_wrapping_shift_harness!(u128, wrapping_shr, checked_wrapping_shr_u128);
1969+
generate_wrapping_shift_harness!(usize, wrapping_shr, checked_wrapping_shr_usize);
19461970
}

library/core/src/num/uint_macros.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2172,6 +2172,7 @@ macro_rules! uint_impl {
21722172
without modifying the original"]
21732173
#[inline(always)]
21742174
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
2175+
#[ensures(|result| *result == self >> (rhs & (Self::BITS - 1)))]
21752176
pub const fn wrapping_shr(self, rhs: u32) -> Self {
21762177
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
21772178
// out of bounds

0 commit comments

Comments
 (0)