forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update expectation for projection of slice reference. (rust-lang#1032)
* Fix 1: Slice projection yields a thin pointer Our expectation did not considered the array decay when creating fat pointers. * Added new testcases for size_of and raw slice * Add test for different representations + fix comment
- Loading branch information
Showing
9 changed files
with
575 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
Checking harness check_non_empty_raw... | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: mem::size_of_val(raw) == 4"\ | ||
slice.rs:61:5 in function check_non_empty_raw | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: raw.inner.len() == 4"\ | ||
slice.rs:62:5 in function check_non_empty_raw | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: raw.inner[0] == 1"\ | ||
slice.rs:63:5 in function check_non_empty_raw | ||
|
||
VERIFICATION:- SUCCESSFUL | ||
|
||
Checking harness check_empty_raw... | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: mem::size_of_val(raw) == 0"\ | ||
slice.rs:70:5 in function check_empty_raw | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: raw.inner.len() == 0"\ | ||
slice.rs:71:5 in function check_empty_raw | ||
|
||
VERIFICATION:- SUCCESSFUL | ||
|
||
Checking harness check_non_empty_slice... | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: mem::size_of_val(slice) == 2"\ | ||
slice.rs:78:5 in function check_non_empty_slice | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.others.len() == 1"\ | ||
slice.rs:79:5 in function check_non_empty_slice | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.first == 1"\ | ||
slice.rs:80:5 in function check_non_empty_slice | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.others[0] == 5"\ | ||
slice.rs:81:5 in function check_non_empty_slice | ||
|
||
VERIFICATION:- SUCCESSFUL | ||
|
||
|
||
Checking harness check_naive_iterator_should_fail... | ||
|
||
Status: SUCCESS\ | ||
Description: ""Naive new should have the wrong slice len""\ | ||
slice.rs:94:5 in function check_naive_iterator_should_fail | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.first == first"\ | ||
slice.rs:95:5 in function check_naive_iterator_should_fail | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.others[0] == second"\ | ||
slice.rs:96:5 in function check_naive_iterator_should_fail | ||
|
||
Status: FAILURE\ | ||
Description: "dereference failure: pointer outside object bounds"\ | ||
slice.rs:100:32 in function check_naive_iterator_should_fail | ||
|
||
VERIFICATION:- FAILED | ||
|
||
|
||
Summary:\ | ||
Verification failed for - check_naive_iterator_should_fail\ | ||
Complete - 3 successfully verified harnesses, 1 failures, 4 total. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: --unwind 3 | ||
|
||
//! This test case has a bunch of checks related to structures using raw slices ([T]). | ||
use std::mem; | ||
|
||
/// Non-sized structure with a sized element and an unsized element. | ||
struct NonEmptySlice { | ||
first: u8, | ||
others: [u8], | ||
} | ||
|
||
/// Non-sized structure with only an unsized element. | ||
struct RawSlice { | ||
inner: [u8], | ||
} | ||
|
||
impl NonEmptySlice { | ||
/// This creates a NonEmptySlice from a byte slice. | ||
/// | ||
/// Note that the cast operation keep the the fat pointer structure, so we need to manually | ||
/// create the expected pointer with correct len. For the NonEmptySlice, this looks like: | ||
/// ```rust | ||
/// struct NonEmptySliceRef { | ||
/// ptr: *const u8, | ||
/// unsize_len: usize, | ||
/// } | ||
/// ``` | ||
/// | ||
/// I.e.: The length is only relative to the unsized part of the structure. | ||
/// The total size of the object is the `size_of(sized_members) + (unsize_len * size_of::<u8>())` | ||
/// | ||
fn new(bytes: &mut [u8]) -> &Self { | ||
assert!(bytes.len() > 0, "This requires at least one element"); | ||
let unsized_len = bytes.len() - 1; | ||
unsafe { | ||
let ptr = std::ptr::slice_from_raw_parts_mut(bytes.as_mut_ptr(), unsized_len); | ||
unsafe { &*(ptr as *mut Self) } | ||
} | ||
} | ||
|
||
/// This function does a naive transmute in the slice which generates a corrupt structure. | ||
/// See the documentation of `NonEmptySliceRef::new()` for more details. | ||
fn naive_new(bytes: &mut [u8]) -> &Self { | ||
assert!(bytes.len() > 0, "This requires at least one element"); | ||
unsafe { std::mem::transmute(bytes) } | ||
} | ||
} | ||
|
||
impl RawSlice { | ||
fn new(bytes: &mut [u8]) -> &Self { | ||
unsafe { std::mem::transmute(bytes) } | ||
} | ||
} | ||
|
||
#[kani::proof] | ||
fn check_non_empty_raw() { | ||
let mut vector = vec![1u8, 2u8, 3u8, 4u8]; | ||
let raw = RawSlice::new(vector.as_mut_slice()); | ||
assert_eq!(mem::size_of_val(raw), 4); | ||
assert_eq!(raw.inner.len(), 4); | ||
assert_eq!(raw.inner[0], 1); | ||
} | ||
|
||
#[kani::proof] | ||
fn check_empty_raw() { | ||
let mut vector = vec![]; | ||
let raw = RawSlice::new(vector.as_mut_slice()); | ||
assert_eq!(mem::size_of_val(raw), 0); | ||
assert_eq!(raw.inner.len(), 0); | ||
} | ||
|
||
#[kani::proof] | ||
fn check_non_empty_slice() { | ||
let mut vector = vec![1u8, 5u8]; | ||
let slice = NonEmptySlice::new(vector.as_mut_slice()); | ||
assert_eq!(mem::size_of_val(slice), 2); | ||
assert_eq!(slice.others.len(), 1); | ||
assert_eq!(slice.first, 1); | ||
assert_eq!(slice.others[0], 5); | ||
} | ||
|
||
#[kani::proof] | ||
#[kani::unwind(3)] | ||
fn check_naive_iterator_should_fail() { | ||
let mut bytes = vec![1u8, 5u8]; | ||
assert_eq!(bytes.len(), 2); | ||
|
||
let first = bytes[0]; | ||
let second = bytes[1]; | ||
|
||
let slice = NonEmptySlice::naive_new(&mut bytes); | ||
assert_eq!(slice.others.len(), 2, "Naive new should have the wrong slice len"); | ||
assert_eq!(slice.first, first); | ||
assert_eq!(slice.others[0], second); | ||
let mut sum = 0u8; | ||
for e in &slice.others { | ||
// This should trigger out-of-bounds. | ||
sum = sum.wrapping_add(*e); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
Checking harness check_non_empty_raw... | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: mem::size_of_val(raw) == 4"\ | ||
in function check_non_empty_raw | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: raw.inner.len() == 4"\ | ||
in function check_non_empty_raw | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: raw.inner[0] == 1"\ | ||
in function check_non_empty_raw | ||
|
||
VERIFICATION:- SUCCESSFUL | ||
|
||
Checking harness check_empty_raw... | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: mem::size_of_val(raw) == 0"\ | ||
in function check_empty_raw | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: raw.inner.len() == 0"\ | ||
in function check_empty_raw | ||
|
||
VERIFICATION:- SUCCESSFUL | ||
|
||
Checking harness check_non_empty_slice... | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: mem::size_of_val(slice) == 2"\ | ||
in function check_non_empty_slice | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.others.len() == 1"\ | ||
in function check_non_empty_slice | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.first == 1"\ | ||
in function check_non_empty_slice | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.others[0] == 5"\ | ||
in function check_non_empty_slice | ||
|
||
VERIFICATION:- SUCCESSFUL | ||
|
||
|
||
Checking harness check_naive_iterator_should_fail... | ||
|
||
Status: SUCCESS\ | ||
Description: ""Naive new should have the wrong slice len""\ | ||
in function check_naive_iterator_should_fail | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.first == first"\ | ||
in function check_naive_iterator_should_fail | ||
|
||
Status: SUCCESS\ | ||
Description: "assertion failed: slice.others[0] == second"\ | ||
in function check_naive_iterator_should_fail | ||
|
||
Status: FAILURE\ | ||
Description: "dereference failure: pointer outside object bounds"\ | ||
in function check_naive_iterator_should_fail | ||
|
||
VERIFICATION:- FAILED | ||
|
||
|
||
Summary:\ | ||
Verification failed for - check_naive_iterator_should_fail\ | ||
Complete - 3 successfully verified harnesses, 1 failures, 4 total. |
Oops, something went wrong.