-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow modifies clause for verification only
Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
- Loading branch information
1 parent
f8c30d9
commit 62bdf68
Showing
13 changed files
with
192 additions
and
70 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
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
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
3 changes: 3 additions & 0 deletions
3
tests/expected/function-contract/modifies/check_invalid_modifies.expected
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,3 @@ | ||
error: `&str` doesn't implement `kani::Arbitrary`. Callee: `kani::Arbitrary::any` \ | ||
Please, check whether the type of all objects in the modifies clause (including return types) implement `kani::Arbitrary`. \ | ||
This is a strict condition to use function contracts as verified stubs. |
27 changes: 27 additions & 0 deletions
27
tests/expected/function-contract/modifies/check_invalid_modifies.rs
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,27 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Zfunction-contracts | ||
|
||
//! Check that Kani reports the correct error message when modifies clause | ||
//! includes objects of types that do not implement `kani::Arbitrary`. | ||
//! This restriction is only applied when using contracts as verified stubs. | ||
#[kani::requires(*ptr < 100)] | ||
#[kani::modifies(ptr)] | ||
fn modify(ptr: &mut u32) -> &'static str { | ||
*ptr += 1; | ||
let msg: &'static str = "done"; | ||
msg | ||
} | ||
|
||
fn use_modify(ptr: &mut u32) { | ||
*ptr = 99; | ||
assert!(modify(ptr) == "done"); | ||
} | ||
|
||
#[kani::proof] | ||
#[kani::stub_verified(modify)] | ||
fn harness() { | ||
let mut i = kani::any_where(|x| *x < 100); | ||
use_modify(&mut i); | ||
} |
4 changes: 4 additions & 0 deletions
4
tests/expected/function-contract/modifies/mistake_condition_return.expected
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,4 @@ | ||
Failed Checks: assertion failed: res == 100 \ | ||
File: "mistake_condition_return.rs", line 31, in use_modify \ | ||
|
||
VERIFICATION:- FAILED |
39 changes: 39 additions & 0 deletions
39
tests/expected/function-contract/modifies/mistake_condition_return.rs
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,39 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Zfunction-contracts | ||
|
||
//! Provide an example where users might get confuse on how to constrain | ||
//! the return value of functions when writing function contracts. | ||
//! In this case, users must remember that when using contracts as | ||
//! verified stubs, the return value will be havoced. To retrict the return | ||
//! value of a function, users may use the `result` keyword in their | ||
//! ensures clauses. | ||
#[kani::requires(*ptr < 100)] | ||
#[kani::modifies(ptr)] | ||
// In this case, one may think that by assuming `*ptr == 100`, automatically | ||
// we can assume the return value of this function will also be equal to 100. | ||
// However, contract instrumentation will create a separate non-deterministic | ||
// value to return in this function that can only be constrained by using the | ||
// `result` keyword. Thus the correct condition would be | ||
// `#[kani::ensures(result == 100)]`. | ||
#[kani::ensures(*ptr == 100)] | ||
fn modify(ptr: &mut u32) -> u32 { | ||
*ptr += 1; | ||
*ptr | ||
} | ||
|
||
fn use_modify(ptr: &mut u32) { | ||
*ptr = 99; | ||
let res = modify(ptr); | ||
// This assertion won't hold because the return | ||
// value of `modify` is unconstrained. | ||
assert!(res == 100); | ||
} | ||
|
||
#[kani::proof] | ||
#[kani::stub_verified(modify)] | ||
fn harness() { | ||
let mut i = kani::any(); | ||
use_modify(&mut i); | ||
} |
1 change: 1 addition & 0 deletions
1
tests/expected/function-contract/modifies/simple_only_verification.expected
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 @@ | ||
VERIFICATION:- SUCCESSFUL |
22 changes: 22 additions & 0 deletions
22
tests/expected/function-contract/modifies/simple_only_verification.rs
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,22 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Zfunction-contracts | ||
|
||
//! Check that is possible to use `modifies` clause for verifciation, but not stubbing. | ||
//! Using contracts as verified stubs require users to ensure the type of any object in | ||
//! the modifies clause (including return types) to implement `kani::Arbitrary`. | ||
//! This requirement is not necessary if the contract is only used for verification. | ||
#[kani::requires(*ptr < 100)] | ||
#[kani::modifies(ptr)] | ||
fn modify(ptr: &mut u32) -> &'static str { | ||
*ptr += 1; | ||
let msg: &'static str = "done"; | ||
msg | ||
} | ||
|
||
#[kani::proof_for_contract(modify)] | ||
fn harness() { | ||
let mut i = kani::any_where(|x| *x < 100); | ||
modify(&mut i); | ||
} |