Skip to content

Commit

Permalink
Do not turn trivially diverging loops into assume(false) (#3223)
Browse files Browse the repository at this point in the history
CBMC's symbolic execution by default turns `while(true) {}` loops into
`assume(false)` to counter trivial non-termination of symbolic
execution. When unwinding assertions are enabled, however, we should
report the non-termination of such loops.

Resolves: #2909
  • Loading branch information
tautschnig authored Jun 8, 2024
1 parent ffcb5ad commit adc1f0d
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
2 changes: 2 additions & 0 deletions kani-driver/src/call_cbmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ impl KaniSession {
}

if self.args.checks.unwinding_on() {
// TODO: With CBMC v6 the below can be removed as those are defaults.
args.push("--unwinding-assertions".into());
args.push("--no-self-loops-to-assumptions".into());
}

if self.args.extra_pointer_checks {
Expand Down
3 changes: 3 additions & 0 deletions tests/expected/function-contract/diverging_loop.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Failed Checks: unwinding assertion loop 0

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

#[kani::ensures(|result : &i32| *result == 1)]
fn foo() -> i32 {
loop {}
2
}

#[kani::proof_for_contract(foo)]
#[kani::unwind(1)]
fn check_foo() {
let _ = foo();
}

0 comments on commit adc1f0d

Please sign in to comment.