Skip to content

Commit 4d9af86

Browse files
adpaco-awstedinski
authored andcommitted
Update raw_eq documentation and tests (rust-lang#1091)
* Update `raw_eq` documentation * Updates test and adds two more * Comment from review
1 parent 3ae60f3 commit 4d9af86

File tree

5 files changed

+57
-11
lines changed

5 files changed

+57
-11
lines changed

docs/src/rust-feature-support.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ ensure there is no resource leak or persistent data inconsistency. Check out
192192
[this issue](https://github.com/model-checking/kani/issues/692) for updates on
193193
stack unwinding support.
194194

195+
### Uninitialized memory
196+
197+
Reading uninitialized memory is
198+
[considered undefined behavior](https://doc.rust-lang.org/reference/behavior-considered-undefined.html#behavior-considered-undefined) in Rust.
199+
At the moment, Kani cannot detect if memory is uninitialized, but in practice
200+
this is mitigated by the fact that all memory is initialized with
201+
nondeterministic values.
202+
Therefore, any code that depends on uninitialized data will exhibit nondeterministic behavior.
203+
See [this issue](https://github.com/model-checking/kani/issues/920) for more details.
204+
195205
### Destructors
196206

197207
At present, we are aware of some issues with destructors, in particular those
@@ -374,7 +384,7 @@ prefetch_write_instruction | No | |
374384
ptr_guaranteed_eq | Partial | |
375385
ptr_guaranteed_ne | Partial | |
376386
ptr_offset_from | Partial | Missing undefined behavior checks |
377-
raw_eq | Partial | Missing undefined behavior checks |
387+
raw_eq | Partial | Cannot detect [uninitialized memory](#uninitialized-memory) |
378388
rintf32 | No | |
379389
rintf64 | No | |
380390
rotate_left | Yes | |

kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -933,13 +933,15 @@ impl<'tcx> GotocCtx<'tcx> {
933933
}
934934

935935
// `raw_eq` determines whether the raw bytes of two values are equal.
936-
// https://stdrs.dev/nightly/x86_64-pc-windows-gnu/std/intrinsics/fn.raw_eq.html
936+
// https://doc.rust-lang.org/core/intrinsics/fn.raw_eq.html
937937
//
938938
// The implementation below calls `memcmp` and returns equal if the result is zero.
939939
//
940-
// TODO: Handle more cases in this intrinsic by looking into the parameters' layouts.
941-
// TODO: Fix soundness issues in this intrinsic. It's UB to call `raw_eq` if any of
942-
// the bytes in the first or second arguments are uninitialized.
940+
// TODO: It's UB to call `raw_eq` if any of the bytes in the first or second
941+
// arguments are uninitialized. At present, we cannot detect if there is
942+
// uninitialized memory, but `raw_eq` would basically return a nondet. value
943+
// when one of the arguments is uninitialized.
944+
// https://github.com/model-checking/kani/issues/920
943945
fn codegen_intrinsic_raw_eq(
944946
&mut self,
945947
instance: Instance<'tcx>,

tests/kani/Intrinsics/raw_eq.rs renamed to tests/kani/Intrinsics/RawEq/main.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Check that we get the expected results for the `raw_eq` intrinsic
35
#![feature(core_intrinsics)]
4-
#![feature(const_intrinsic_raw_eq)]
5-
#![deny(const_err)]
6+
use std::intrinsics::raw_eq;
67

78
#[kani::proof]
89
fn main() {
9-
// Check that we get the expected results for the `raw_eq` intrinsic
10-
use std::intrinsics::raw_eq;
11-
1210
let raw_eq_i32_true: bool = unsafe { raw_eq(&42_i32, &42) };
1311
assert!(raw_eq_i32_true);
1412

@@ -24,6 +22,6 @@ fn main() {
2422
let raw_eq_array_true: bool = unsafe { raw_eq(&[13_u8, 42], &[13, 42]) };
2523
assert!(raw_eq_array_true);
2624

27-
const raw_eq_array_false: bool = unsafe { raw_eq(&[13_u8, 42], &[42, 13]) };
25+
let raw_eq_array_false: bool = unsafe { raw_eq(&[13_u8, 42], &[42, 13]) };
2826
assert!(!raw_eq_array_false);
2927
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// kani-verify-fail
4+
5+
// Checks that `raw_eq` cannot determine equality when one of the arguments is
6+
// uninitialized
7+
#![feature(core_intrinsics)]
8+
use std::intrinsics::raw_eq;
9+
use std::mem::{zeroed, MaybeUninit};
10+
11+
#[kani::proof]
12+
fn main() {
13+
let zeroed_arr: [u8; 8] = unsafe { zeroed() };
14+
let uninit_arr: [u8; 8] = unsafe { MaybeUninit::uninit().assume_init() };
15+
16+
let arr_are_eq = unsafe { raw_eq(&zeroed_arr, &uninit_arr) };
17+
assert!(arr_are_eq);
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// kani-verify-fail
4+
5+
// Checks that `raw_eq` cannot determine inequality when one of the arguments
6+
// is uninitialized
7+
#![feature(core_intrinsics)]
8+
use std::intrinsics::raw_eq;
9+
use std::mem::{zeroed, MaybeUninit};
10+
11+
#[kani::proof]
12+
fn main() {
13+
let zeroed_arr: [u8; 8] = unsafe { zeroed() };
14+
let uninit_arr: [u8; 8] = unsafe { MaybeUninit::uninit().assume_init() };
15+
16+
let arr_are_eq = unsafe { raw_eq(&zeroed_arr, &uninit_arr) };
17+
assert!(!arr_are_eq);
18+
}

0 commit comments

Comments
 (0)