Skip to content

Commit 8f799d2

Browse files
committed
Update Rc verification after upstream rebase
1 parent 6ce45e7 commit 8f799d2

2 files changed

Lines changed: 11 additions & 57 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ These are the challenges:
5050
| [23: Verify the safety of Vec functions part 1](https://model-checking.github.io/verify-rust-std/challenges/0023-vec-pt1.html) | 15,000 USD | Open | |
5151
| [24: Verify the safety of Vec functions part 2](https://model-checking.github.io/verify-rust-std/challenges/0024-vec-pt2.html) | 15,000 USD | Open | |
5252
| [25: Verify the safety of `VecDeque` functions](https://model-checking.github.io/verify-rust-std/challenges/0025-vecdeque.html) | 10,000 USD | Open | |
53-
| [26: Verify reference-counted Cell implementation](https://model-checking.github.io/verify-rust-std/challenges/0026-rc.html) | 10,000 USD | [Resolved](https://github.com/model-checking/verify-rust-std/pull/582) | [Kani](https://github.com/model-checking/verify-rust-std/blob/main/library/alloc/src/rc.rs) |
53+
| [26: Verify reference-counted Cell implementation](https://model-checking.github.io/verify-rust-std/challenges/0026-rc.html) | 10,000 USD | [Resolved](https://github.com/model-checking/verify-rust-std/pull/582) | [Kani](https://github.com/model-checking/verify-rust-std/blob/main/library/alloc/src/rcs/rc.rs) |
5454
| [27: Verify atomically reference-counted Cell implementation](https://model-checking.github.io/verify-rust-std/challenges/0027-arc.html) | 10,000 USD | Open | |
5555
| [28: Verify float to decimal conversion module](https://model-checking.github.io/verify-rust-std/challenges/0028-flt2dec.html) | 5,000 USD | Open | |
5656
| [29: Safety of `boxed`](https://model-checking.github.io/verify-rust-std/challenges/0029-boxed.html) | 15,000 USD | Open | |

‎library/alloc/src/rcs/rc.rs‎

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7524,15 +7524,10 @@ mod verify {
75247524
[u128]
75257525
);
75267526

7527-
// `inc_strong` has two behavior paths:
7528-
// 1) non-overflow path: `strong.wrapping_add(1) != 0`, then return normally;
7529-
// 2) overflow path: `strong.wrapping_add(1) == 0`, then call `abort()`.
7530-
//
7531-
// Coverage strategy in this module:
7532-
// - `*_non_overflow` harnesses build normal live `Rc` values, so strong starts from a valid
7533-
// non-zero count and follows path (1).
7534-
// - `harness_inc_strong_overflow_should_panic` forges `strong == usize::MAX` right before the
7535-
// call, so `wrapping_add` becomes 0 and path (2) is forced.
7527+
// `inc_strong` has two execution paths:
7528+
// - Non-overflow path: verified by the harnesses below.
7529+
// - Overflow path: temporarily unverified because the pinned Kani
7530+
// version does not support `intrinsics::abort_immediate()`.
75367531
// RcInnerPtr::inc_strong harnesses.
75377532
macro_rules! gen_inc_strong_non_overflow_sized_harness {
75387533
($name:ident, $ty:ty) => {
@@ -7573,22 +7568,6 @@ mod verify {
75737568
};
75747569
}
75757570

7576-
#[kani::proof]
7577-
#[kani::should_panic]
7578-
pub fn harness_inc_strong_overflow_should_panic() {
7579-
// Start from a valid allocation, then force the pre-state for overflow branch.
7580-
let rc: Rc<u8, Global> = Rc::new_in(kani::any::<u8>(), Global);
7581-
let inner = rc.inner();
7582-
// Force `strong == usize::MAX`, so `wrapping_add(1)` becomes 0.
7583-
inner.strong_ref().set(usize::MAX);
7584-
// This must hit the overflow check and abort.
7585-
assert!(inner.strong() == usize::MAX);
7586-
kani::cover(true, "inc_strong overflow starts from usize::MAX");
7587-
inner.inc_strong();
7588-
// If execution reaches here, overflow branch was not taken as expected.
7589-
core::mem::forget(rc);
7590-
}
7591-
75927571
gen_inc_strong_non_overflow_sized_harness!(harness_inc_strong_i8, i8);
75937572
gen_inc_strong_non_overflow_sized_harness!(harness_inc_strong_i16, i16);
75947573
gen_inc_strong_non_overflow_sized_harness!(harness_inc_strong_i32, i32);
@@ -7609,18 +7588,10 @@ mod verify {
76097588
gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u64, [u64]);
76107589
gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u128, [u128]);
76117590

7612-
// `inc_weak` has two behavior paths controlled by the post-increment value:
7613-
// 1) non-overflow path: `weak.wrapping_add(1) != 0`, function returns normally;
7614-
// 2) overflow path: `weak.wrapping_add(1) == 0`, function aborts.
7615-
//
7616-
// Trigger conditions:
7617-
// - Path (1): call `inc_weak` from a regular live allocation, where weak starts from a
7618-
// valid non-zero count.
7619-
// - Path (2): force `weak == usize::MAX` immediately before calling `inc_weak`.
7620-
//
7621-
// Coverage in this module:
7622-
// - `*_non_overflow` harnesses cover path (1) for sized and unsized values.
7623-
// - `harness_inc_weak_overflow_should_panic` covers path (2).
7591+
// `inc_weak` has two execution paths:
7592+
// - Non-overflow path: verified by the harnesses below.
7593+
// - Overflow path: temporarily unverified because the pinned Kani
7594+
// version does not support `intrinsics::abort_immediate()`.
76247595
// RcInnerPtr::inc_weak harnesses.
76257596
macro_rules! gen_inc_weak_non_overflow_sized_harness {
76267597
($name:ident, $ty:ty) => {
@@ -7661,22 +7632,6 @@ mod verify {
76617632
};
76627633
}
76637634

7664-
#[kani::proof]
7665-
#[kani::should_panic]
7666-
pub fn harness_inc_weak_overflow_should_panic() {
7667-
// Start from a valid allocation and force overflow pre-state.
7668-
let rc: Rc<u8, Global> = Rc::new_in(kani::any::<u8>(), Global);
7669-
let inner = rc.inner();
7670-
// Force `weak == usize::MAX` so `wrapping_add(1)` becomes zero.
7671-
inner.weak_ref().set(usize::MAX);
7672-
// Trigger path (2): overflow should abort.
7673-
assert!(inner.weak() == usize::MAX);
7674-
kani::cover(true, "inc_weak overflow starts from usize::MAX");
7675-
inner.inc_weak();
7676-
// Avoid dropping forged state if panic handling changes.
7677-
core::mem::forget(rc);
7678-
}
7679-
76807635
gen_inc_weak_non_overflow_sized_harness!(harness_inc_weak_i8, i8);
76817636
gen_inc_weak_non_overflow_sized_harness!(harness_inc_weak_i16, i16);
76827637
gen_inc_weak_non_overflow_sized_harness!(harness_inc_weak_i32, i32);
@@ -8344,7 +8299,6 @@ mod verify {
83448299
#[kani::proof]
83458300
pub fn $name() {
83468301
let value: $ty = kani::any::<$ty>();
8347-
let rc: Rc<$ty> = Rc::new(value);
83488302
// Call the target function: this harness verifies `Rc::new`.
83498303
let rc: Rc<$ty> = Rc::new(value);
83508304
assert!(*rc == value);
@@ -8869,8 +8823,8 @@ mod verify {
88698823
pub fn $name() {
88708824
let vec = verifier_nondet_vec_rc::<$ty>();
88718825
let rc: Rc<[$ty]> = Rc::from(vec);
8872-
// N matches the helper's length bound so both the Some (len == N)
8873-
// and None (len != N) return arms are reachable.
8826+
// N lies within the helper's possible length range,
8827+
// so both Ok (len == N) and Err (len != N) are reachable.
88748828
const N: usize = 12;
88758829
let len = rc.len();
88768830
let expected_data = Rc::as_ptr(&rc) as *const $ty;

0 commit comments

Comments
 (0)