Skip to content

Commit 0e4e241

Browse files
celinvaladpaco-aws
andauthored
Do not override std library during playback (model-checking#2852)
We override a few std functions to improve verification time or verification results, however, those functions are quite helpful during concrete execution. Thus, avoid overriding functions when executing concrete playback. Resolves model-checking#2850 Co-authored-by: Adrian Palacios <[email protected]>
1 parent f22f885 commit 0e4e241

File tree

5 files changed

+90
-0
lines changed

5 files changed

+90
-0
lines changed

library/std/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ pub use std::*;
1515
// Bind `core::assert` to a different name to avoid possible name conflicts if a
1616
// crate uses `extern crate std as core`. See
1717
// https://github.com/model-checking/kani/issues/1949
18+
#[cfg(not(feature = "concrete_playback"))]
1819
#[allow(unused_imports)]
1920
use core::assert as __kani__workaround_core_assert;
2021

22+
#[cfg(not(feature = "concrete_playback"))]
2123
// Override process calls with stubs.
2224
pub mod process;
2325

@@ -41,6 +43,7 @@ pub mod process;
4143
/// ```
4244
/// the assert message will be:
4345
/// "The sum of {} and {} is {}", a, b, c
46+
#[cfg(not(feature = "concrete_playback"))]
4447
#[macro_export]
4548
macro_rules! assert {
4649
($cond:expr $(,)?) => {
@@ -77,6 +80,7 @@ macro_rules! assert {
7780
// (see https://github.com/model-checking/kani/issues/13)
7881
// 3. Call kani::assert so that any instrumentation that it does (e.g. injecting
7982
// reachability checks) is done for assert_eq and assert_ne
83+
#[cfg(not(feature = "concrete_playback"))]
8084
#[macro_export]
8185
macro_rules! assert_eq {
8286
($left:expr, $right:expr $(,)?) => ({
@@ -89,6 +93,7 @@ macro_rules! assert_eq {
8993
});
9094
}
9195

96+
#[cfg(not(feature = "concrete_playback"))]
9297
#[macro_export]
9398
macro_rules! assert_ne {
9499
($left:expr, $right:expr $(,)?) => ({
@@ -102,45 +107,53 @@ macro_rules! assert_ne {
102107
}
103108

104109
// Treat the debug assert macros same as non-debug ones
110+
#[cfg(not(feature = "concrete_playback"))]
105111
#[macro_export]
106112
macro_rules! debug_assert {
107113
($($x:tt)*) => ({ $crate::assert!($($x)*); })
108114
}
109115

116+
#[cfg(not(feature = "concrete_playback"))]
110117
#[macro_export]
111118
macro_rules! debug_assert_eq {
112119
($($x:tt)*) => ({ $crate::assert_eq!($($x)*); })
113120
}
114121

122+
#[cfg(not(feature = "concrete_playback"))]
115123
#[macro_export]
116124
macro_rules! debug_assert_ne {
117125
($($x:tt)*) => ({ $crate::assert_ne!($($x)*); })
118126
}
119127

120128
// Override the print macros to skip all the printing functionality (which
121129
// is not relevant for verification)
130+
#[cfg(not(feature = "concrete_playback"))]
122131
#[macro_export]
123132
macro_rules! print {
124133
($($x:tt)*) => {{ let _ = format_args!($($x)*); }};
125134
}
126135

136+
#[cfg(not(feature = "concrete_playback"))]
127137
#[macro_export]
128138
macro_rules! eprint {
129139
($($x:tt)*) => {{ let _ = format_args!($($x)*); }};
130140
}
131141

142+
#[cfg(not(feature = "concrete_playback"))]
132143
#[macro_export]
133144
macro_rules! println {
134145
() => { };
135146
($($x:tt)*) => {{ let _ = format_args!($($x)*); }};
136147
}
137148

149+
#[cfg(not(feature = "concrete_playback"))]
138150
#[macro_export]
139151
macro_rules! eprintln {
140152
() => { };
141153
($($x:tt)*) => {{ let _ = format_args!($($x)*); }};
142154
}
143155

156+
#[cfg(not(feature = "concrete_playback"))]
144157
#[macro_export]
145158
macro_rules! unreachable {
146159
// The argument, if present, is a literal that represents the error message, i.e.:
@@ -171,6 +184,7 @@ macro_rules! unreachable {
171184
stringify!($fmt, $($arg)*)))}};
172185
}
173186

187+
#[cfg(not(feature = "concrete_playback"))]
174188
#[macro_export]
175189
macro_rules! panic {
176190
// No argument is given.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
script: playback_print.sh
4+
expected: expected
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
internal error: entered unreachable code: oops
2+
3+
assertion `left == right` failed: Found 1 != 0
4+
left: 1
5+
right: 0
6+
7+
assertion `left == right` failed
8+
left: 0
9+
right: 1
10+
11+
Found value 2
12+
13+
test result: FAILED. 0 passed; 4 failed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
# Copyright Kani Contributors
3+
# SPDX-License-Identifier: Apache-2.0 OR MIT
4+
5+
# Test that concrete playback does not override std print functions
6+
7+
set -o nounset
8+
9+
function error() {
10+
echo $@
11+
# Cleanup
12+
rm ${RS_FILE}
13+
rm output.log
14+
exit 1
15+
}
16+
17+
RS_FILE="modified.rs"
18+
cp print_vars.rs ${RS_FILE}
19+
export RUSTFLAGS="--edition 2021"
20+
21+
echo "[TEST] Generate test..."
22+
kani ${RS_FILE} -Z concrete-playback --concrete-playback=inplace
23+
24+
echo "[TEST] Run test..."
25+
kani playback -Z concrete-playback ${RS_FILE} 2>&1 | tee output.log
26+
27+
echo "------ Check output ----------"
28+
29+
set -e
30+
while read -r line; do
31+
grep "${line}" output.log || error "Failed to find: \"${line}\""
32+
done < expected
33+
34+
echo
35+
echo "------ Output OK ----------"
36+
echo
37+
38+
# Cleanup
39+
rm ${RS_FILE}
40+
rm output.log
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//
4+
// Harness used to test that playback do not override assertion and panic functions.
5+
6+
#[kani::proof]
7+
pub fn harness() {
8+
let v1: u32 = kani::any();
9+
let v2: u32 = kani::any();
10+
// avoid direct assignments to v1 to block constant propagation.
11+
kani::assume(v1 == v2);
12+
13+
match v2 {
14+
0 => assert_eq!(v1, 1),
15+
1 => assert_eq!(v1, 0, "Found {v1} != 0"),
16+
2 => panic!("Found value {v1}"),
17+
_ => unreachable!("oops"),
18+
}
19+
}

0 commit comments

Comments
 (0)