Skip to content

Commit 571e269

Browse files
adpaco-awstedinski
authored andcommitted
Audit for ptr_guaranteed_<cmp> (rust-lang#1090)
* Audit for `ptr_guaranteed_<cmp>` * Update docs * Add two tests
1 parent 6b68180 commit 571e269

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

docs/src/rust-feature-support.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ prefetch_read_data | No | |
381381
prefetch_read_instruction | No | |
382382
prefetch_write_data | No | |
383383
prefetch_write_instruction | No | |
384-
ptr_guaranteed_eq | Partial | |
385-
ptr_guaranteed_ne | Partial | |
384+
ptr_guaranteed_eq | Yes | |
385+
ptr_guaranteed_ne | Yes | |
386386
ptr_offset_from | Partial | Missing undefined behavior checks |
387387
raw_eq | Partial | Cannot detect [uninitialized memory](#uninitialized-memory) |
388388
rintf32 | No | |

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ impl<'tcx> GotocCtx<'tcx> {
246246
($f:ident) => {{ codegen_intrinsic_binop!($f) }};
247247
}
248248

249-
// Intrinsics which encode a simple binary operation
250-
macro_rules! codegen_intrinsic_boolean_binop {
249+
// Intrinsics which encode a pointer comparison (e.g., `ptr_guaranteed_eq`).
250+
// These behave as regular pointer comparison at runtime:
251+
// https://doc.rust-lang.org/beta/std/primitive.pointer.html#method.guaranteed_eq
252+
macro_rules! codegen_ptr_guaranteed_cmp {
251253
($f:ident) => {{ self.binop(p, fargs, |a, b| a.$f(b).cast_to(Type::c_bool())) }};
252254
}
253255

@@ -519,8 +521,8 @@ impl<'tcx> GotocCtx<'tcx> {
519521
"powif32" => unstable_codegen!(codegen_simple_intrinsic!(Powif)),
520522
"powif64" => unstable_codegen!(codegen_simple_intrinsic!(Powi)),
521523
"pref_align_of" => codegen_intrinsic_const!(),
522-
"ptr_guaranteed_eq" => codegen_intrinsic_boolean_binop!(eq),
523-
"ptr_guaranteed_ne" => codegen_intrinsic_boolean_binop!(neq),
524+
"ptr_guaranteed_eq" => codegen_ptr_guaranteed_cmp!(eq),
525+
"ptr_guaranteed_ne" => codegen_ptr_guaranteed_cmp!(neq),
524526
"ptr_offset_from" => self.codegen_ptr_offset_from(fargs, p, loc),
525527
"raw_eq" => self.codegen_intrinsic_raw_eq(instance, fargs, p, loc),
526528
"rintf32" => codegen_unimplemented_intrinsic!(
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Checks that `ptr_guaranteed_eq` returns true if the pointers are equal, false
5+
// otherwise.
6+
#![feature(core_intrinsics)]
7+
use std::intrinsics::ptr_guaranteed_eq;
8+
9+
#[kani::proof]
10+
fn test_ptr_eq_eq(ptr1: *const u8, ptr2: *const u8) {
11+
kani::assume(ptr1 == ptr2);
12+
assert!(ptr_guaranteed_eq(ptr1, ptr2));
13+
}
14+
15+
#[kani::proof]
16+
fn test_ptr_eq_ne(ptr1: *const u8, ptr2: *const u8) {
17+
kani::assume(ptr1 != ptr2);
18+
assert!(!ptr_guaranteed_eq(ptr1, ptr2));
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Checks that `ptr_guaranteed_ne` returns true if the pointers are different,
5+
// false otherwise.
6+
#![feature(core_intrinsics)]
7+
use std::intrinsics::ptr_guaranteed_ne;
8+
9+
#[kani::proof]
10+
fn test_ptr_ne_ne(ptr1: *const u8, ptr2: *const u8) {
11+
kani::assume(ptr1 != ptr2);
12+
assert!(ptr_guaranteed_ne(ptr1, ptr2));
13+
}
14+
15+
#[kani::proof]
16+
fn test_ptr_ne_eq(ptr1: *const u8, ptr2: *const u8) {
17+
kani::assume(ptr1 == ptr2);
18+
assert!(!ptr_guaranteed_ne(ptr1, ptr2));
19+
}

0 commit comments

Comments
 (0)