Skip to content

Commit 37e06ce

Browse files
committed
Add loop contracts and harness for ptr::swap_nonoverlapping_simple_untyped
1 parent bd56a76 commit 37e06ce

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

library/alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
#![feature(unboxed_closures)]
194194
#![feature(unsized_fn_params)]
195195
#![feature(with_negative_coherence)]
196+
#![cfg_attr(kani, feature(proc_macro_hygiene))]
196197
#![rustc_preserve_ub_checks]
197198
// tidy-alphabetical-end
198199
//

library/core/src/ptr/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
12021202
let x = x.cast::<MaybeUninit<T>>();
12031203
let y = y.cast::<MaybeUninit<T>>();
12041204
let mut i = 0;
1205+
#[safety::loop_invariant(i <= count)]
12051206
while i < count {
12061207
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
12071208
let x = unsafe { x.add(i) };
@@ -2623,4 +2624,18 @@ mod verify {
26232624
let m = kani::any::<usize>();
26242625
unsafe { mod_inv_copy(x, m) };
26252626
}
2627+
2628+
#[kani::proof]
2629+
pub fn check_swap_nonoverlapping_simple_untyped() {
2630+
const ARR_SIZE: usize = (2 << 32) -1;
2631+
let mut x: [u8; ARR_SIZE] = kani::any();
2632+
let mut xs = kani::slice::any_slice_of_array_mut(&mut x);
2633+
let mut y: [u8; ARR_SIZE] = kani::any();
2634+
let mut ys = kani::slice::any_slice_of_array_mut(&mut y);
2635+
let s: usize = kani::any_where(|v| *v <= xs.len() && *v <= ys.len());
2636+
unsafe {
2637+
swap_nonoverlapping_simple_untyped(xs.as_mut_ptr(), ys.as_mut_ptr(), s);
2638+
}
2639+
}
2640+
26262641
}

0 commit comments

Comments
 (0)