Skip to content

Commit 8df4908

Browse files
committed
Avoid global path conditions in Kani's library
There is no need to maintain global path conditions in order to constrain non-deterministic data: we can locally pick an arbitrary one of the permitted values. This avoids propagating guards on input data across all properties subsequently seen in symbolic execution.
1 parent 588baf0 commit 8df4908

File tree

3 files changed

+34
-18
lines changed

3 files changed

+34
-18
lines changed

library/kani/src/arbitrary.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ trivial_arbitrary!(());
7676
impl Arbitrary for bool {
7777
#[inline(always)]
7878
fn any() -> Self {
79-
let byte = u8::any();
80-
crate::assume(byte < 2);
79+
let byte = u8::any() & 0x1;
8180
byte == 1
8281
}
8382
}
@@ -88,9 +87,13 @@ impl Arbitrary for char {
8887
#[inline(always)]
8988
fn any() -> Self {
9089
// Generate an arbitrary u32 and constrain it to make it a valid representation of char.
91-
let val = u32::any();
92-
crate::assume(val <= 0xD7FF || (0xE000..=0x10FFFF).contains(&val));
93-
unsafe { char::from_u32_unchecked(val) }
90+
let val = u32::any() & 0x0FFFFF;
91+
if val & 0xD800 != 0 {
92+
// val > 0xD7FF && val < 0xE000
93+
unsafe { char::from_u32_unchecked(0x10FFFF) }
94+
} else {
95+
unsafe { char::from_u32_unchecked(val) }
96+
}
9497
}
9598
}
9699

@@ -100,8 +103,11 @@ macro_rules! nonzero_arbitrary {
100103
#[inline(always)]
101104
fn any() -> Self {
102105
let val = <$base>::any();
103-
crate::assume(val != 0);
104-
unsafe { <$type>::new_unchecked(val) }
106+
if val == 0 {
107+
unsafe { <$type>::new_unchecked(1) }
108+
} else {
109+
unsafe { <$type>::new_unchecked(val) }
110+
}
105111
}
106112
}
107113
};

library/kani/src/slice.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright Kani Contributors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
3-
use crate::{any, assume, Arbitrary};
3+
use crate::{any, Arbitrary};
44
use std::alloc::{alloc, dealloc, Layout};
55
use std::ops::{Deref, DerefMut};
66

@@ -30,9 +30,13 @@ pub fn any_slice_of_array_mut<T, const LENGTH: usize>(arr: &mut [T; LENGTH]) ->
3030
fn any_range<const LENGTH: usize>() -> (usize, usize) {
3131
let from: usize = any();
3232
let to: usize = any();
33-
assume(to <= LENGTH);
34-
assume(from <= to);
35-
(from, to)
33+
if to > LENGTH {
34+
(0, 0)
35+
} else if to < from {
36+
(0, 0)
37+
} else {
38+
(from, to)
39+
}
3640
}
3741

3842
/// A struct that stores a slice of type `T` with a non-deterministic length
@@ -80,10 +84,15 @@ impl<T, const MAX_SLICE_LENGTH: usize> AnySlice<T, MAX_SLICE_LENGTH> {
8084

8185
fn alloc_slice() -> Self {
8286
let slice_len = any();
83-
assume(slice_len <= MAX_SLICE_LENGTH);
84-
let layout = Layout::array::<T>(slice_len).unwrap();
85-
let ptr = if slice_len == 0 { std::ptr::null() } else { unsafe { alloc(layout) } };
86-
Self { layout, ptr: ptr as *mut T, slice_len }
87+
if slice_len <= MAX_SLICE_LENGTH {
88+
let layout = Layout::array::<T>(slice_len).unwrap();
89+
let ptr = if slice_len == 0 { std::ptr::null() } else { unsafe { alloc(layout) } };
90+
Self { layout, ptr: ptr as *mut T, slice_len }
91+
} else {
92+
let layout = Layout::array::<T>(0).unwrap();
93+
let ptr: *const T = std::ptr::null();
94+
Self { layout, ptr: ptr as *mut T, slice_len }
95+
}
8796
}
8897

8998
pub fn get_slice(&self) -> &[T] {

library/kani/src/vec.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright Kani Contributors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
3-
use crate::{any, assume, Arbitrary};
3+
use crate::{any, Arbitrary};
44

55
/// Generates an arbitrary vector whose length is at most MAX_LENGTH.
66
pub fn any_vec<T, const MAX_LENGTH: usize>() -> Vec<T>
@@ -10,8 +10,9 @@ where
1010
{
1111
let mut v = exact_vec::<T, MAX_LENGTH>();
1212
let real_length: usize = any();
13-
assume(real_length <= MAX_LENGTH);
14-
unsafe { v.set_len(real_length) };
13+
if real_length <= MAX_LENGTH {
14+
unsafe { v.set_len(real_length) };
15+
}
1516

1617
v
1718
}

0 commit comments

Comments
 (0)