Skip to content

Commit

Permalink
fix: Allow multiple stub_verifieds on a single harness
Browse files Browse the repository at this point in the history
  • Loading branch information
ShoyuVanilla committed Jan 2, 2025
1 parent 7913e3c commit 85f9129
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
12 changes: 7 additions & 5 deletions kani-compiler/src/kani_middle/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl<'tcx> KaniAttributes<'tcx> {
attrs.iter().for_each(|attr| self.check_proof_attribute(kind, attr))
}
KaniAttributeKind::StubVerified => {
expect_single(self.tcx, kind, &attrs);
self.parse_stub_verifieds();
}
KaniAttributeKind::FnMarker
| KaniAttributeKind::CheckedWith
Expand Down Expand Up @@ -519,7 +519,7 @@ impl<'tcx> KaniAttributes<'tcx> {
}
KaniAttributeKind::Proof => { /* no-op */ }
KaniAttributeKind::ProofForContract => self.handle_proof_for_contract(&mut harness),
KaniAttributeKind::StubVerified => self.handle_stub_verified(&mut harness),
KaniAttributeKind::StubVerified => harness.verified_stubs.extend_from_slice(&self.parse_stub_verifieds()),
KaniAttributeKind::Unstable => {
// Internal attribute which shouldn't exist here.
unreachable!()
Expand Down Expand Up @@ -566,8 +566,9 @@ impl<'tcx> KaniAttributes<'tcx> {
}
}

fn handle_stub_verified(&self, harness: &mut HarnessAttributes) {
fn parse_stub_verifieds(&self) -> Vec<String> {
let dcx = self.tcx.dcx();
let mut verified_stubs = Vec::new();
for (name, def_id, span) in self.interpret_stub_verified_attribute() {
if KaniAttributes::for_item(self.tcx, def_id).contract_attributes().is_none() {
dcx.struct_span_err(
Expand All @@ -585,10 +586,11 @@ impl<'tcx> KaniAttributes<'tcx> {
),
)
.emit();
return;
return verified_stubs;
}
harness.verified_stubs.push(name.to_string())
verified_stubs.push(name.to_string());
}
verified_stubs
}

fn item_name(&self) -> Symbol {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.assertion\
- Status: SUCCESS\
- Description: "divisor != 0"

.assertion\
- Status: SUCCESS\
- Description: "a >= b"

main.assertion\
- Status: SUCCESS\
- Description: ""contract guarantees smallness""

VERIFICATION:- SUCCESSFUL
22 changes: 22 additions & 0 deletions tests/expected/function-contract/simple_replace_multiple_pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

#[kani::requires(divisor != 0)]
#[kani::ensures(|result : &u32| *result <= dividend)]
fn div(dividend: u32, divisor: u32) -> u32 {
dividend / divisor
}

#[kani::requires(a >= b)]
#[kani::ensures(|result : &u32| *result <= a)]
fn sub(a: u32, b: u32) -> u32 {
a - b
}

#[kani::proof]
#[kani::stub_verified(div)]
#[kani::stub_verified(sub)]
fn main() {
assert!(div(sub(9, 1), 1) != 10, "contract guarantees smallness");
}

0 comments on commit 85f9129

Please sign in to comment.