Skip to content

Commit 7769825

Browse files
committed
Fix regression
1 parent 5f4a69b commit 7769825

File tree

3 files changed

+43
-34
lines changed

3 files changed

+43
-34
lines changed

library/kani/src/mem.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ where
6363
T: ?Sized,
6464
<T as Pointee>::Metadata: PtrProperties<T>,
6565
{
66+
// The interface takes a mutable pointer to improve readability of the signature.
67+
// However, using constant pointer avoid unnecessary instrumentation, and it is as powerful.
68+
// Hence, cast to `*const T`.
69+
let ptr: *const T = ptr;
6670
let (thin_ptr, metadata) = ptr.to_raw_parts();
6771
metadata.is_ptr_aligned(thin_ptr, Internal) && is_inbounds(&metadata, thin_ptr)
6872
}
@@ -244,6 +248,10 @@ unsafe fn is_allocated(_ptr: *const (), _size: usize) -> bool {
244248
}
245249

246250
/// Check if the value stored in the given location satisfies type `T` validity requirements.
251+
///
252+
/// # Safety
253+
///
254+
/// - Users have to ensure that the pointer is aligned the pointed memory is allocated.
247255
#[rustc_diagnostic_item = "KaniValidValue"]
248256
#[inline(never)]
249257
unsafe fn has_valid_value<T: ?Sized>(_ptr: *const T) -> bool {
@@ -252,7 +260,7 @@ unsafe fn has_valid_value<T: ?Sized>(_ptr: *const T) -> bool {
252260

253261
#[cfg(test)]
254262
mod tests {
255-
use super::{can_write, PtrProperties};
263+
use super::{can_dereference, can_write, PtrProperties};
256264
use crate::mem::private::Internal;
257265
use std::fmt::Debug;
258266
use std::intrinsics::size_of;
@@ -306,39 +314,42 @@ mod tests {
306314

307315
#[test]
308316
pub fn test_empty_slice() {
309-
let slice_ptr = Vec::<char>::new().as_slice() as *const [char];
310-
can_write(slice_ptr);
317+
let slice_ptr = Vec::<char>::new().as_mut_slice() as *mut [char];
318+
assert!(can_write(slice_ptr));
311319
}
312320

313321
#[test]
314322
pub fn test_empty_str() {
315-
let slice_ptr = String::new().as_str() as *const str;
316-
can_write(slice_ptr);
323+
let slice_ptr = String::new().as_mut_str() as *mut str;
324+
assert!(can_write(slice_ptr));
317325
}
318326

319327
#[test]
320328
fn test_dangling_zst() {
321-
test_dangling_of_t::<()>();
322-
test_dangling_of_t::<[(); 10]>();
329+
test_dangling_of_zst::<()>();
330+
test_dangling_of_zst::<[(); 10]>();
323331
}
324332

325-
fn test_dangling_of_t<T>() {
326-
let dangling: *const T = NonNull::<T>::dangling().as_ptr();
327-
can_write(dangling);
333+
fn test_dangling_of_zst<T>() {
334+
let dangling: *mut T = NonNull::<T>::dangling().as_ptr();
335+
assert!(can_write(dangling));
328336

329-
let vec_ptr = Vec::<T>::new().as_ptr();
330-
can_write(vec_ptr);
337+
let vec_ptr = Vec::<T>::new().as_mut_ptr();
338+
assert!(can_write(vec_ptr));
331339
}
332340

333341
#[test]
334-
#[should_panic(expected = "Expected valid pointer, but found `null`")]
335342
fn test_null_fat_ptr() {
336-
can_write(ptr::null::<char>() as *const dyn Debug);
343+
assert!(!can_dereference(ptr::null::<char>() as *const dyn Debug));
337344
}
338345

339346
#[test]
340-
#[should_panic(expected = "Expected valid pointer, but found `null`")]
341347
fn test_null_char() {
342-
can_write(ptr::null::<char>());
348+
assert!(!can_dereference(ptr::null::<char>()));
349+
}
350+
351+
#[test]
352+
fn test_null_mut() {
353+
assert!(!can_write(ptr::null_mut::<String>()));
343354
}
344355
}

tests/kani/MemPredicates/fat_ptr_validity.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,22 @@
55
66
extern crate kani;
77

8-
use kani::mem::assert_valid_ptr;
8+
use kani::mem::{can_dereference, can_write};
99

1010
mod valid_access {
1111
use super::*;
1212
#[kani::proof]
1313
pub fn check_valid_dyn_ptr() {
14-
let boxed: Box<dyn PartialEq<u8>> = Box::new(10u8);
15-
let raw_ptr = Box::into_raw(boxed);
16-
assert_valid_ptr(raw_ptr);
17-
let boxed = unsafe { Box::from_raw(raw_ptr) };
18-
assert_ne!(*boxed, 0);
14+
let mut var = 10u8;
15+
let fat_ptr: *mut dyn PartialEq<u8> = &mut var as *mut _;
16+
assert!(can_write(fat_ptr));
1917
}
2018

2119
#[kani::proof]
2220
pub fn check_valid_slice_ptr() {
2321
let array = ['a', 'b', 'c'];
2422
let slice = &array as *const [char];
25-
assert_valid_ptr(slice);
23+
assert!(can_dereference(slice));
2624
assert_eq!(unsafe { &*slice }[0], 'a');
2725
assert_eq!(unsafe { &*slice }[2], 'c');
2826
}
@@ -43,14 +41,14 @@ mod invalid_access {
4341
#[kani::should_panic]
4442
pub fn check_invalid_dyn_ptr() {
4543
let raw_ptr: *const dyn PartialEq<u8> = unsafe { new_dead_ptr::<u8>(0) };
46-
assert_valid_ptr(raw_ptr);
44+
assert!(can_dereference(raw_ptr));
4745
}
4846

4947
#[kani::proof]
5048
#[kani::should_panic]
5149
pub fn check_invalid_slice_ptr() {
5250
let raw_ptr: *const [char] = unsafe { new_dead_ptr::<[char; 2]>(['a', 'b']) };
53-
assert_valid_ptr(raw_ptr);
51+
assert!(can_dereference(raw_ptr));
5452
}
5553

5654
#[kani::proof]
@@ -59,7 +57,7 @@ mod invalid_access {
5957
let array = [10usize; 10];
6058
let invalid: *const [usize; 11] = &array as *const [usize; 10] as *const [usize; 11];
6159
let ptr: *const [usize] = invalid as *const _;
62-
assert_valid_ptr(ptr);
60+
assert!(can_dereference(ptr));
6361
}
6462

6563
unsafe fn new_dead_ptr<T>(val: T) -> *const T {

tests/kani/MemPredicates/thin_ptr_validity.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,27 @@
55
66
extern crate kani;
77

8-
use kani::mem::assert_valid_ptr;
8+
use kani::mem::can_dereference;
99
use std::ptr::NonNull;
1010

1111
mod valid_access {
1212
use super::*;
1313
#[kani::proof]
1414
pub fn check_dangling_zst() {
1515
let dangling = NonNull::<()>::dangling().as_ptr();
16-
assert_valid_ptr(dangling);
16+
assert!(can_dereference(dangling));
1717

1818
let vec_ptr = Vec::<()>::new().as_ptr();
19-
assert_valid_ptr(vec_ptr);
19+
assert!(can_dereference(vec_ptr));
2020

2121
let dangling = NonNull::<[char; 0]>::dangling().as_ptr();
22-
assert_valid_ptr(dangling);
22+
assert!(can_dereference(dangling));
2323
}
2424

2525
#[kani::proof]
2626
pub fn check_valid_array() {
2727
let array = ['a', 'b', 'c'];
28-
assert_valid_ptr(&array);
28+
assert!(can_dereference(&array));
2929
}
3030
}
3131

@@ -35,22 +35,22 @@ mod invalid_access {
3535
#[kani::should_panic]
3636
pub fn check_invalid_ptr() {
3737
let raw_ptr = unsafe { new_dead_ptr::<u8>(0) };
38-
assert_valid_ptr(raw_ptr);
38+
assert!(!can_dereference(raw_ptr));
3939
}
4040

4141
#[kani::proof]
4242
#[kani::should_panic]
4343
pub fn check_invalid_array() {
4444
let raw_ptr = unsafe { new_dead_ptr::<[char; 2]>(['a', 'b']) };
45-
assert_valid_ptr(raw_ptr);
45+
assert!(can_dereference(raw_ptr));
4646
}
4747

4848
#[kani::proof]
4949
pub fn check_invalid_zst() {
5050
let raw_ptr: *const [char; 0] =
5151
unsafe { new_dead_ptr::<[char; 2]>(['a', 'b']) } as *const _;
5252
// ZST pointer are always valid
53-
assert_valid_ptr(raw_ptr);
53+
assert!(can_dereference(raw_ptr));
5454
}
5555

5656
unsafe fn new_dead_ptr<T>(val: T) -> *const T {

0 commit comments

Comments
 (0)