Skip to content

Commit

Permalink
Change same_allocation to accept wide pointers (#3684)
Browse files Browse the repository at this point in the history
For that, change the function to cast the given pointer to a thin
pointer of type `*const ()`, and use that instead.

Resolves #3665

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
  • Loading branch information
celinval authored Nov 6, 2024
1 parent 0dc09a7 commit 4aa739f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
18 changes: 8 additions & 10 deletions library/kani_core/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ macro_rules! kani_mem {
reason = "experimental memory predicate API"
)]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn same_allocation<T>(ptr1: *const T, ptr2: *const T) -> bool {
pub fn same_allocation<T: ?Sized>(ptr1: *const T, ptr2: *const T) -> bool {
cbmc::same_allocation(ptr1, ptr2)
}

Expand Down Expand Up @@ -337,18 +337,16 @@ macro_rules! kani_mem {
pub(super) mod cbmc {
use super::*;
/// CBMC specific implementation of [super::same_allocation].
pub fn same_allocation<T>(ptr1: *const T, ptr2: *const T) -> bool {
let obj1 = crate::kani::mem::pointer_object(ptr1);
(obj1 == crate::kani::mem::pointer_object(ptr2)) && {
pub fn same_allocation<T: ?Sized>(ptr1: *const T, ptr2: *const T) -> bool {
let addr1 = ptr1 as *const ();
let addr2 = ptr2 as *const ();
let obj1 = crate::kani::mem::pointer_object(addr1);
(obj1 == crate::kani::mem::pointer_object(addr2)) && {
crate::kani::assert(
unsafe {
is_allocated(ptr1 as *const (), 0) || is_allocated(ptr2 as *const (), 0)
},
unsafe { is_allocated(addr1, 0) || is_allocated(addr2, 0) },
"Kani does not support reasoning about pointer to unallocated memory",
);
unsafe {
is_allocated(ptr1 as *const (), 0) && is_allocated(ptr2 as *const (), 0)
}
unsafe { is_allocated(addr1, 0) && is_allocated(addr2, 0) }
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions tests/kani/MemPredicates/same_allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern crate kani;

use kani::mem::same_allocation;
use kani::{AllocationStatus, ArbitraryPointer, PointerGenerator};
use std::any::Any;

#[kani::proof]
fn check_inbounds() {
Expand Down Expand Up @@ -54,3 +55,45 @@ fn check_dyn_alloc() {
let ArbitraryPointer { ptr: ptr2, .. } = generator2.any_in_bounds::<u8>();
assert!(!same_allocation(ptr1a, ptr2));
}

#[kani::proof]
fn check_same_alloc_dyn_ptr() {
let mut generator = PointerGenerator::<100>::new();
let ArbitraryPointer { ptr: ptr1, .. } = generator.any_in_bounds::<()>();
let ArbitraryPointer { ptr: ptr2, .. } = generator.any_in_bounds::<char>();
let dyn_1 = ptr1 as *const dyn Any;
let dyn_2 = ptr2 as *const dyn Any;
assert!(same_allocation(dyn_1, dyn_2));
}

#[kani::proof]
fn check_not_same_alloc_dyn_ptr() {
let mut generator1 = PointerGenerator::<100>::new();
let mut generator2 = PointerGenerator::<100>::new();
let ArbitraryPointer { ptr: ptr1, .. } = generator1.any_in_bounds::<()>();
let ArbitraryPointer { ptr: ptr2, .. } = generator2.any_in_bounds::<char>();
let dyn_1 = ptr1 as *const dyn Any;
let dyn_2 = ptr2 as *const dyn Any;
assert!(!same_allocation(dyn_1, dyn_2));
}

#[kani::proof]
fn check_same_alloc_slice() {
let mut generator = PointerGenerator::<100>::new();
let ArbitraryPointer { ptr: ptr1, .. } = generator.any_in_bounds::<[u16; 4]>();
let ArbitraryPointer { ptr: ptr2, .. } = generator.any_in_bounds::<[u16; 10]>();
let slice_1 = ptr1 as *const [_];
let slice_2 = ptr2 as *const [_];
assert!(same_allocation(slice_1, slice_2));
}

#[kani::proof]
fn check_not_same_alloc_slice() {
let mut generator1 = PointerGenerator::<100>::new();
let mut generator2 = PointerGenerator::<100>::new();
let ArbitraryPointer { ptr: ptr1, .. } = generator1.any_in_bounds::<[u16; 4]>();
let ArbitraryPointer { ptr: ptr2, .. } = generator2.any_in_bounds::<[u16; 10]>();
let slice_1 = ptr1 as *const [_];
let slice_2 = ptr2 as *const [_];
assert!(!same_allocation(slice_1, slice_2));
}

0 comments on commit 4aa739f

Please sign in to comment.