Skip to content

Commit 6acc2cf

Browse files
tedinskitautschnigdanielsn
authored
Rewrite loops with multiple back edges to having a single back edge only (rust-lang#1117)
rustc reasonably translates if statements at end of a loop body to backwards jumps to the loop head. This, however, causes CBMC's symbolic execution to spuriously treat these as nested loops. This commit now enables a rewrite step that had previously been built for exactly such cases. This treatment as nested loops implied that seemingly lower unwinding bounds were sufficient (as the loop unwinding counter got reset). Three of the tests exhibited this behaviour, which now makes larger unwinding bounds necessary. Fixes: rust-lang#1046 Co-authored-by: Daniel Schwartz-Narbonne <[email protected]> Co-authored-by: Michael Tautschnig <[email protected]> Co-authored-by: Daniel Schwartz-Narbonne <[email protected]>
1 parent 8fe6559 commit 6acc2cf

File tree

4 files changed

+14
-7
lines changed

4 files changed

+14
-7
lines changed

docs/src/tutorial/arbitrary-variables/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ vector-map = "1.0.1"
1111
[workspace]
1212

1313
[workspace.metadata.kani]
14-
flags = { default-checks = false, unwind = "2" }
14+
flags = { unwind = "3" }

kani-driver/src/call_goto_instrument.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ impl KaniSession {
2323
self.just_drop_unused_functions(output)?;
2424
}
2525

26+
self.rewrite_back_edges(output)?;
27+
2628
if self.args.gen_c {
2729
if !self.args.quiet {
2830
println!("Generated C code written to {}", output.to_string_lossy());
@@ -100,6 +102,16 @@ impl KaniSession {
100102
self.call_goto_instrument(args)
101103
}
102104

105+
fn rewrite_back_edges(&self, file: &Path) -> Result<()> {
106+
let args: Vec<OsString> = vec![
107+
"--ensure-one-backedge-per-target".into(),
108+
file.to_owned().into_os_string(), // input
109+
file.to_owned().into_os_string(), // output
110+
];
111+
112+
self.call_goto_instrument(args)
113+
}
114+
103115
/// Generate a .c file from a goto binary (i.e. --gen-c)
104116
pub fn gen_c(&self, file: &Path) -> Result<()> {
105117
let output_filename = alter_extension(file, "c");

tests/kani/AssociatedTypes/into_iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl<'a> MyStruct<'a> {
1919
}
2020

2121
#[kani::proof]
22-
#[kani::unwind(2)]
22+
#[kani::unwind(3)]
2323
pub fn check_into_iter_type() {
2424
let original = "h";
2525
let mut wrapper = MyStruct::new(original.chars());

tests/kani/Intrinsics/Count/ctpop.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ macro_rules! test_ctpop {
2020
if bit != 0 {
2121
count += 1;
2222
}
23-
// The assertion below mitigates a low performance issue in this
24-
// test due to the loop having a conditional jump at the end,
25-
// see https://github.com/model-checking/kani/issues/1046 for
26-
// more details.
27-
assert!(count >= 0);
2823
}
2924
count
3025
}

0 commit comments

Comments
 (0)