|
4 | 4 | // collections, resulting in having to optimize down excess IR multiple times.
|
5 | 5 | // Your performance intuition is useless. Run perf.
|
6 | 6 |
|
| 7 | +use safety::requires; |
7 | 8 | use crate::cmp;
|
8 | 9 | use crate::error::Error;
|
9 | 10 | use crate::fmt;
|
10 | 11 | use crate::mem;
|
11 | 12 | use crate::ptr::{Alignment, NonNull};
|
12 | 13 |
|
| 14 | +#[cfg(kani)] |
| 15 | +use crate::kani; |
| 16 | + |
13 | 17 | // While this function is used in one place and its implementation
|
14 | 18 | // could be inlined, the previous attempts to do so made rustc
|
15 | 19 | // slower:
|
@@ -117,6 +121,9 @@ impl Layout {
|
117 | 121 | #[must_use]
|
118 | 122 | #[inline]
|
119 | 123 | #[rustc_allow_const_fn_unstable(ptr_alignment_type)]
|
| 124 | + #[requires(align > 0)] |
| 125 | + #[requires((align & (align - 1)) == 0)] |
| 126 | + #[requires(size <= isize::MAX as usize - (align - 1))] |
120 | 127 | pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
|
121 | 128 | // SAFETY: the caller is required to uphold the preconditions.
|
122 | 129 | unsafe { Layout { size, align: Alignment::new_unchecked(align) } }
|
@@ -492,3 +499,26 @@ impl fmt::Display for LayoutError {
|
492 | 499 | f.write_str("invalid parameters to Layout::from_size_align")
|
493 | 500 | }
|
494 | 501 | }
|
| 502 | + |
| 503 | +#[cfg(kani)] |
| 504 | +#[unstable(feature="kani", issue="none")] |
| 505 | +mod verify { |
| 506 | + use super::*; |
| 507 | + |
| 508 | + #[kani::proof_for_contract(Layout::from_size_align_unchecked)] |
| 509 | + pub fn check_from_size_align_unchecked() { |
| 510 | + let shift_index = kani::any::<usize>(); |
| 511 | + kani::assume(shift_index < core::mem::size_of::<usize>() * 8); |
| 512 | + let a : usize = 1 << shift_index; |
| 513 | + kani::assume(a > 0); |
| 514 | + |
| 515 | + let s = kani::any::<usize>(); |
| 516 | + kani::assume(s <= isize::MAX as usize - (a - 1)); |
| 517 | + |
| 518 | + unsafe { |
| 519 | + let layout = Layout::from_size_align_unchecked(s, a); |
| 520 | + assert_eq!(layout.size(), s); |
| 521 | + assert_eq!(layout.align(), a); |
| 522 | + } |
| 523 | + } |
| 524 | +} |
0 commit comments