-
Notifications
You must be signed in to change notification settings - Fork 111
/
Copy pathvalid_ptr.rs
56 lines (46 loc) · 1.6 KB
/
valid_ptr.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts -Zmem-predicates
//! Test that it is sound to use memory predicates inside a contract pre-condition.
mod pre_condition {
/// This contract should succeed only if the input is a valid pointer.
#[kani::requires(kani::mem::can_dereference(ptr))]
unsafe fn read_ptr(ptr: *const i32) -> i32 {
*ptr
}
#[kani::proof_for_contract(read_ptr)]
fn harness_head_ptr() {
let boxed = Box::new(10);
let raw_ptr = Box::into_raw(boxed);
assert_eq!(unsafe { read_ptr(raw_ptr) }, 10);
let _ = unsafe { Box::from_raw(raw_ptr) };
}
#[kani::proof_for_contract(read_ptr)]
fn harness_stack_ptr() {
let val = -20;
assert_eq!(unsafe { read_ptr(&val) }, -20);
}
#[kani::proof_for_contract(read_ptr)]
fn harness_invalid_ptr() {
let ptr = std::ptr::NonNull::<i32>::dangling().as_ptr();
assert_eq!(unsafe { read_ptr(ptr) }, -20);
}
}
mod post_condition {
/// This contract should fail since we are creating a dangling pointer.
#[kani::ensures(|result| kani::mem::can_dereference(result.0))]
unsafe fn new_invalid_ptr() -> PtrWrapper<char> {
let var = 'c';
PtrWrapper(&var as *const _)
}
#[kani::proof_for_contract(new_invalid_ptr)]
fn harness() {
let _ = unsafe { new_invalid_ptr() };
}
struct PtrWrapper<T>(*const T);
impl<T> kani::Arbitrary for PtrWrapper<T> {
fn any() -> Self {
unreachable!("Do not invoke stubbing")
}
}
}