Skip to content

Commit 5424bc5

Browse files
authored
Remove assigns clause for ZST pointers (#3417)
This PR filters out ZST pointee types when generating CMBC assigns clauses for contracts. This prevents CMBC from complaining that the pointer doesn't point to a valid allocation. Resolves #3181 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent b24c01b commit 5424bc5

File tree

7 files changed

+37
-13
lines changed

7 files changed

+37
-13
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright Kani Contributors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
3-
use crate::codegen_cprover_gotoc::GotocCtx;
3+
use crate::codegen_cprover_gotoc::{codegen::ty_stable::pointee_type_stable, GotocCtx};
44
use crate::kani_middle::attributes::KaniAttributes;
55
use cbmc::goto_program::FunctionContract;
66
use cbmc::goto_program::{Expr, Lambda, Location, Type};
@@ -160,11 +160,17 @@ impl<'tcx> GotocCtx<'tcx> {
160160
let TyKind::RigidTy(RigidTy::Tuple(modifies_tys)) = modifies_ty.kind() else {
161161
unreachable!("found {:?}", modifies_ty.kind())
162162
};
163+
164+
for ty in &modifies_tys {
165+
assert!(ty.kind().is_any_ptr(), "Expected pointer, but found {}", ty);
166+
}
167+
163168
let assigns: Vec<_> = modifies_tys
164169
.into_iter()
170+
// do not attempt to dereference (and assign) a ZST
171+
.filter(|ty| !self.is_zst_stable(pointee_type_stable(*ty).unwrap()))
165172
.enumerate()
166173
.map(|(idx, ty)| {
167-
assert!(ty.kind().is_any_ptr(), "Expected pointer, but found {}", ty);
168174
let ptr = modifies_args.clone().member(idx.to_string(), &self.symbol_table);
169175
if self.is_fat_pointer_stable(ty) {
170176
let unref = match ty.kind() {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.assertion\
2+
- Status: SUCCESS\
3+
- Description: "ptr NULL or writable up to size"\
4+
5+
VERIFICATION:- SUCCESSFUL
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// kani-flags: -Zfunction-contracts
4+
5+
#[kani::modifies(dst)]
6+
pub unsafe fn replace<T>(dst: *mut T, src: T) -> T {
7+
std::ptr::replace(dst, src)
8+
}
9+
10+
#[kani::proof_for_contract(replace)]
11+
pub fn check_replace_unit() {
12+
check_replace_impl::<()>();
13+
}
14+
15+
fn check_replace_impl<T: kani::Arbitrary + Eq + Clone>() {
16+
let mut dst = T::any();
17+
let orig = dst.clone();
18+
let src = T::any();
19+
let ret = unsafe { replace(&mut dst, src.clone()) };
20+
assert_eq!(ret, orig);
21+
assert_eq!(dst, src);
22+
}

tests/std-checks/core/mem.expected

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
Checking harness mem::verify::check_swap_unit...
22

3-
Failed Checks: ptr NULL or writable up to size
4-
5-
Summary:
6-
Verification failed for - mem::verify::check_swap_unit
7-
Complete - 6 successfully verified harnesses, 1 failures, 7 total.
3+
Complete - 7 successfully verified harnesses, 0 failures, 7 total.

tests/std-checks/core/ptr.expected

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
Summary:
2-
Verification failed for - ptr::verify::check_replace_unit
32
Verification failed for - ptr::verify::check_as_ref_dangling
4-
Complete - 4 successfully verified harnesses, 2 failures, 6 total.
3+
Complete - 5 successfully verified harnesses, 1 failures, 6 total.

tests/std-checks/core/src/mem.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ mod verify {
4848
contracts::swap(&mut x, &mut y)
4949
}
5050

51-
/// FIX-ME: Modifies clause fail with pointer to ZST.
52-
/// <https://github.com/model-checking/kani/issues/3181>
5351
#[kani::proof_for_contract(contracts::swap)]
5452
pub fn check_swap_unit() {
5553
let mut x: () = kani::any();

tests/std-checks/core/src/ptr.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ mod verify {
8989
let _rf = unsafe { contracts::as_ref(&non_null) };
9090
}
9191

92-
/// FIX-ME: Modifies clause fail with pointer to ZST.
93-
/// <https://github.com/model-checking/kani/issues/3181>
9492
#[kani::proof_for_contract(contracts::replace)]
9593
pub fn check_replace_unit() {
9694
check_replace_impl::<()>();

0 commit comments

Comments
 (0)