Skip to content

Commit 72a28c9

Browse files
committed
prove correctness of layout len utilities with kani
proves that `round_down_to_next_multiple_of_alignment` and `padding_needed_for` are equivalent to model implementations.
1 parent cc7a0eb commit 72a28c9

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/util.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,51 @@ mod tests {
149149
}
150150
}
151151
}
152+
153+
#[cfg(kani)]
154+
mod proofs {
155+
use super::*;
156+
157+
#[kani::proof]
158+
fn prove_round_down_to_next_multiple_of_alignment() {
159+
fn model_impl(n: usize, align: NonZeroUsize) -> usize {
160+
assert!(align.get().is_power_of_two());
161+
let mul = n / align.get();
162+
mul * align.get()
163+
}
164+
165+
let align: NonZeroUsize = kani::any();
166+
kani::assume(align.get().is_power_of_two());
167+
let n: usize = kani::any();
168+
169+
let expected = model_impl(n, align);
170+
let actual = _round_down_to_next_multiple_of_alignment(n, align);
171+
assert_eq!(expected, actual, "round_down_to_next_multiple_of_alignment({n}, {align})");
172+
}
173+
174+
// Restricted to nightly since we use the unstable `usize::next_multiple_of`
175+
// in our model implementation.
176+
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
177+
#[kani::proof]
178+
fn prove_padding_needed_for() {
179+
fn model_impl(len: usize, align: NonZeroUsize) -> usize {
180+
let padded = len.next_multiple_of(align.get());
181+
let padding = padded - len;
182+
padding
183+
}
184+
185+
let align: NonZeroUsize = kani::any();
186+
kani::assume(align.get().is_power_of_two());
187+
let len: usize = kani::any();
188+
// Constrain `len` to valid Rust lengths, since our model implementation
189+
// isn't robust to overflow.
190+
kani::assume(len < isize::MAX as usize);
191+
192+
let expected = model_impl(len, align);
193+
let actual = core_layout::_padding_needed_for(len, align);
194+
assert_eq!(expected, actual, "padding_needed_for({len}, {align})");
195+
196+
assert_eq!(actual % align, 0);
197+
assert!(actual / align >= len / align);
198+
}
199+
}

0 commit comments

Comments
 (0)