Skip to content

Commit 3b7aa7b

Browse files
author
Fedor Ryabinin
committed
A bunch of LLM-generated contracts
1 parent 517e11e commit 3b7aa7b

6 files changed

Lines changed: 145 additions & 0 deletions

File tree

library/core/src/hint.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
//!
55
//! Hints may be compile time or runtime.
66
7+
use safety::{ensures,requires};
8+
#[cfg(kani)]
9+
use crate::kani;
10+
#[allow(unused_imports)]
11+
use crate::ub_checks::*;
12+
713
use crate::mem::MaybeUninit;
814
use crate::{intrinsics, ub_checks};
915

@@ -99,6 +105,7 @@ use crate::{intrinsics, ub_checks};
99105
#[stable(feature = "unreachable", since = "1.27.0")]
100106
#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
101107
#[track_caller]
108+
#[requires(false)]
102109
pub const unsafe fn unreachable_unchecked() -> ! {
103110
ub_checks::assert_unsafe_precondition!(
104111
check_language_ub,
@@ -198,6 +205,7 @@ pub const unsafe fn unreachable_unchecked() -> ! {
198205
#[doc(alias = "assume")]
199206
#[stable(feature = "hint_assert_unchecked", since = "1.81.0")]
200207
#[rustc_const_stable(feature = "hint_assert_unchecked", since = "1.81.0")]
208+
#[requires(cond == true)]
201209
pub const unsafe fn assert_unchecked(cond: bool) {
202210
// SAFETY: The caller promised `cond` is true.
203211
unsafe {

library/core/src/iter/adapters/step_by.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use safety::{ensures,requires};
2+
#[cfg(kani)]
3+
use crate::kani;
4+
#[allow(unused_imports)]
5+
use crate::ub_checks::*;
6+
17
use crate::intrinsics;
28
use crate::iter::{TrustedLen, TrustedRandomAccess, from_fn};
39
use crate::num::NonZero;
@@ -40,6 +46,7 @@ impl<I> StepBy<I> {
4046
/// The `step` that was originally passed to `Iterator::step_by(step)`,
4147
/// aka `self.step_minus_one + 1`.
4248
#[inline]
49+
#[requires(self.step_minus_one != usize::MAX)]
4350
fn original_step(&self) -> NonZero<usize> {
4451
// SAFETY: By type invariant, `step_minus_one` cannot be `MAX`, which
4552
// means the addition cannot overflow and the result cannot be zero.

library/core/src/ops/index_range.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use safety::{ensures,requires};
2+
#[cfg(kani)]
3+
use crate::kani;
4+
#[allow(unused_imports)]
5+
use crate::ub_checks::*;
6+
17
use crate::iter::{FusedIterator, TrustedLen};
28
use crate::num::NonZero;
39
use crate::ops::{NeverShortCircuit, Try};
@@ -20,6 +26,7 @@ impl IndexRange {
2026
/// - `start <= end`
2127
#[inline]
2228
#[track_caller]
29+
#[requires(start <= end)]
2330
pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
2431
ub_checks::assert_unsafe_precondition!(
2532
check_library_ub,
@@ -54,6 +61,8 @@ impl IndexRange {
5461
/// # Safety
5562
/// - Can only be called when `start < end`, aka when `len > 0`.
5663
#[inline]
64+
#[requires(self.start < self.end)]
65+
#[cfg_attr(kani, kani::modifies(self))]
5766
unsafe fn next_unchecked(&mut self) -> usize {
5867
debug_assert!(self.start < self.end);
5968

@@ -66,6 +75,8 @@ impl IndexRange {
6675
/// # Safety
6776
/// - Can only be called when `start < end`, aka when `len > 0`.
6877
#[inline]
78+
#[requires(self.start < self.end)]
79+
#[cfg_attr(kani, kani::modifies(self))]
6980
unsafe fn next_back_unchecked(&mut self) -> usize {
7081
debug_assert!(self.start < self.end);
7182

@@ -225,3 +236,34 @@ impl ExactSizeIterator for IndexRange {
225236
unsafe impl TrustedLen for IndexRange {}
226237

227238
impl FusedIterator for IndexRange {}
239+
#[cfg(kani)]
240+
mod verify {
241+
use super::*;
242+
#[kani::proof_for_contract(IndexRange::new_unchecked)]
243+
fn proof_for_index_range_new_unchecked() {
244+
let start = kani::any::<usize>();
245+
let end = kani::any::<usize>();
246+
247+
unsafe { IndexRange::new_unchecked(start, end) };
248+
}
249+
250+
#[kani::proof_for_contract(IndexRange::next_unchecked)]
251+
fn proof_for_index_range_next_unchecked() {
252+
let start = kani::any::<usize>();
253+
let end = kani::any::<usize>();
254+
255+
let mut range = unsafe { IndexRange::new_unchecked(start, end) };
256+
257+
unsafe { range.next_unchecked() };
258+
}
259+
260+
#[kani::proof_for_contract(IndexRange::next_back_unchecked)]
261+
fn proof_for_index_range_next_back_unchecked() {
262+
let start = kani::any::<usize>();
263+
let end = kani::any::<usize>();
264+
265+
let mut range = unsafe { IndexRange::new_unchecked(start, end) };
266+
267+
unsafe { range.next_back_unchecked() };
268+
}
269+
}

library/std/src/sync/mpmc/context.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
//! Thread-local channel context.
22
3+
#![feature(ub_checks)]
4+
use safety::{ensures,requires};
5+
#[cfg(kani)]
6+
#[unstable(feature="kani", issue="none")]
7+
use core::kani;
8+
#[allow(unused_imports)]
9+
#[unstable(feature = "ub_checks", issue = "none")]
10+
use core::ub_checks::*;
11+
312
use super::select::Selected;
413
use super::waker::current_thread_id;
514
use crate::cell::Cell;
@@ -116,6 +125,7 @@ impl Context {
116125
/// # Safety
117126
/// This may only be called from the thread this `Context` belongs to.
118127
#[inline]
128+
#[requires(self.thread_id() == current_thread_id())]
119129
pub unsafe fn wait_until(&self, deadline: Option<Instant>) -> Selected {
120130
loop {
121131
// Check whether an operation has been selected.

library/stdarch/crates/core_arch/src/x86/sse3.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
//! Streaming SIMD Extensions 3 (SSE3)
22
3+
#![feature(ub_checks)]
4+
use safety::{ensures,requires};
5+
#[cfg(kani)]
6+
#[unstable(feature="kani", issue="none")]
7+
use core::kani;
8+
#[allow(unused_imports)]
9+
#[unstable(feature = "ub_checks", issue = "none")]
10+
use core::ub_checks::*;
11+
312
use crate::core_arch::{simd::*, x86::*};
413
use crate::intrinsics::simd::*;
514

@@ -99,6 +108,7 @@ pub fn _mm_hsub_ps(a: __m128, b: __m128) -> __m128 {
99108
#[target_feature(enable = "sse3")]
100109
#[cfg_attr(test, assert_instr(lddqu))]
101110
#[stable(feature = "simd_x86", since = "1.27.0")]
111+
#[requires(can_dereference(mem_addr))]
102112
pub unsafe fn _mm_lddqu_si128(mem_addr: *const __m128i) -> __m128i {
103113
transmute(lddqu(mem_addr as *const _))
104114
}
@@ -260,3 +270,37 @@ mod tests {
260270
assert_eq_m128d(r, _mm_setr_pd(d, d));
261271
}
262272
}
273+
#[cfg(kani)]
274+
mod verify {
275+
use super::*;
276+
277+
#[cfg(kani)]
278+
#[kani::proof_for_contract(unsafe fn _mm_lddqu_si128(mem_addr: *const __m128i) -> __m128i)]
279+
fn proof_mm_lddqu_si128() {
280+
// Create a valid __m128i value
281+
let mut value = [0i32; 4];
282+
283+
// Get a pointer to the value
284+
let ptr: *const __m128i = value.as_ptr() as *const __m128i;
285+
286+
// Call the function with the valid pointer
287+
unsafe {
288+
let _result = _mm_lddqu_si128(ptr);
289+
}
290+
}
291+
292+
#[cfg(kani)]
293+
#[kani::proof_for_contract(unsafe fn _mm_loadddup_pd(mem_addr: *const f64) -> __m128d)]
294+
fn proof_mm_loadddup_pd() {
295+
// Create a valid f64 value
296+
let value: f64 = 0.0;
297+
298+
// Get a pointer to the value
299+
let ptr: *const f64 = &value;
300+
301+
// Call the function with the valid pointer
302+
unsafe {
303+
let _result = _mm_loadddup_pd(ptr);
304+
}
305+
}
306+
}

library/stdarch/crates/core_arch/src/x86/sse41.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
//! Streaming SIMD Extensions 4.1 (SSE4.1)
22
3+
#![feature(ub_checks)]
4+
use safety::{ensures,requires};
5+
#[cfg(kani)]
6+
#[unstable(feature="kani", issue="none")]
7+
use core::kani;
8+
#[allow(unused_imports)]
9+
#[unstable(feature = "ub_checks", issue = "none")]
10+
use core::ub_checks::*;
11+
312
use crate::core_arch::{simd::*, x86::*};
413
use crate::intrinsics::simd::*;
514

@@ -1132,6 +1141,8 @@ pub fn _mm_test_mix_ones_zeros(a: __m128i, mask: __m128i) -> i32 {
11321141
#[target_feature(enable = "sse4.1")]
11331142
#[cfg_attr(test, assert_instr(movntdqa))]
11341143
#[stable(feature = "simd_x86_updates", since = "1.82.0")]
1144+
#[requires(can_dereference(mem_addr))]
1145+
#[requires(mem_addr as usize % 16 == 0)]
11351146
pub unsafe fn _mm_stream_load_si128(mem_addr: *const __m128i) -> __m128i {
11361147
let dst: __m128i;
11371148
crate::arch::asm!(
@@ -1939,3 +1950,26 @@ mod tests {
19391950
assert_eq_m128i(a, r);
19401951
}
19411952
}
1953+
#[cfg(kani)]
1954+
mod verify {
1955+
use super::*;
1956+
#[cfg(kani)]
1957+
#[repr(align(16))]
1958+
struct Aligned16Bytes {
1959+
data: [u8; 16],
1960+
}
1961+
1962+
#[cfg(kani)]
1963+
#[kani::proof_for_contract(_mm_stream_load_si128)]
1964+
fn verify_mm_stream_load_si128() {
1965+
// Allocate memory for __m128i (16 bytes) with proper alignment
1966+
let mut aligned_data = Aligned16Bytes { data: [0u8; 16] };
1967+
let ptr = &aligned_data.data as *const _ as *const __m128i;
1968+
1969+
// Call the function with our properly aligned pointer
1970+
unsafe {
1971+
let _result = _mm_stream_load_si128(ptr);
1972+
// No postconditions to verify
1973+
}
1974+
}
1975+
}

0 commit comments

Comments
 (0)