@@ -30,12 +30,11 @@ pub struct VerificationResult {
30
30
/// The parsed output, message by message, of CBMC. However, the `Result` message has been
31
31
/// removed and is available in `results` instead.
32
32
pub messages : Option < Vec < ParserItem > > ,
33
- /// The `Result` properties in detail.
34
- pub results : Option < Vec < Property > > ,
35
- /// CBMC process exit status. NOTE: Only potentially useful if `status` is `Failure`.
33
+ /// The `Result` properties in detail or the exit_status of CBMC.
34
+ /// Note: CBMC process exit status is only potentially useful if `status` is `Failure`.
36
35
/// Kani will see CBMC report "failure" that's actually success (interpreting "failed"
37
36
/// checks like coverage as expected and desirable.)
38
- pub exit_status : i32 ,
37
+ pub results : Result < Vec < Property > , i32 > ,
39
38
/// The runtime duration of this CBMC invocation.
40
39
pub runtime : Duration ,
41
40
/// Whether concrete playback generated a test
@@ -67,21 +66,17 @@ impl KaniSession {
67
66
68
67
// Spawn the CBMC process and process its output below
69
68
let cbmc_process_opt = self . run_piped ( cmd) ?;
70
- if let Some ( cbmc_process) = cbmc_process_opt {
71
- let output = process_cbmc_output ( cbmc_process, |i| {
72
- kani_cbmc_output_filter (
73
- i,
74
- self . args . extra_pointer_checks ,
75
- self . args . quiet ,
76
- & self . args . output_format ,
77
- )
78
- } ) ?;
79
-
80
- VerificationResult :: from ( output, start_time)
81
- } else {
82
- // None is only ever returned when it's a dry run
83
- VerificationResult :: mock_success ( )
84
- }
69
+ let cbmc_process = cbmc_process_opt. ok_or ( anyhow:: Error :: msg ( "Failed to run cbmc" ) ) ?;
70
+ let output = process_cbmc_output ( cbmc_process, |i| {
71
+ kani_cbmc_output_filter (
72
+ i,
73
+ self . args . extra_pointer_checks ,
74
+ self . args . quiet ,
75
+ & self . args . output_format ,
76
+ )
77
+ } ) ?;
78
+
79
+ VerificationResult :: from ( output, start_time)
85
80
} ;
86
81
87
82
self . gen_and_add_concrete_playback ( harness, & mut verification_results) ?;
@@ -247,8 +242,7 @@ impl VerificationResult {
247
242
VerificationResult {
248
243
status : determine_status_from_properties ( & results) ,
249
244
messages : Some ( items) ,
250
- results : Some ( results) ,
251
- exit_status : output. process_status ,
245
+ results : Ok ( results) ,
252
246
runtime,
253
247
generated_concrete_test : false ,
254
248
}
@@ -257,8 +251,7 @@ impl VerificationResult {
257
251
VerificationResult {
258
252
status : VerificationStatus :: Failure ,
259
253
messages : Some ( items) ,
260
- results : None ,
261
- exit_status : output. process_status ,
254
+ results : Err ( output. process_status ) ,
262
255
runtime,
263
256
generated_concrete_test : false ,
264
257
}
@@ -269,8 +262,7 @@ impl VerificationResult {
269
262
VerificationResult {
270
263
status : VerificationStatus :: Success ,
271
264
messages : None ,
272
- results : None ,
273
- exit_status : 42 , // on success, exit code is ignored, so put something weird here
265
+ results : Ok ( vec ! [ ] ) ,
274
266
runtime : Duration :: from_secs ( 0 ) ,
275
267
generated_concrete_test : false ,
276
268
}
@@ -280,36 +272,38 @@ impl VerificationResult {
280
272
VerificationResult {
281
273
status : VerificationStatus :: Failure ,
282
274
messages : None ,
283
- results : None ,
284
275
// on failure, exit codes in theory might be used,
285
276
// but `mock_failure` should never be used in a context where they will,
286
277
// so again use something weird:
287
- exit_status : 42 ,
278
+ results : Err ( 42 ) ,
288
279
runtime : Duration :: from_secs ( 0 ) ,
289
280
generated_concrete_test : false ,
290
281
}
291
282
}
292
283
293
284
pub fn render ( & self , output_format : & OutputFormat ) -> String {
294
- if let Some ( results) = & self . results {
295
- let show_checks = matches ! ( output_format, OutputFormat :: Regular ) ;
296
- let mut result = format_result ( results, show_checks) ;
297
- writeln ! ( result, "Verification Time: {}s" , self . runtime. as_secs_f32( ) ) . unwrap ( ) ;
298
- result
299
- } else {
300
- let verification_result = console:: style ( "FAILED" ) . red ( ) ;
301
- format ! (
302
- "\n CBMC failed with status {}\n VERIFICATION:- {verification_result}\n " ,
303
- self . exit_status
304
- )
285
+ match & self . results {
286
+ Ok ( results) => {
287
+ let show_checks = matches ! ( output_format, OutputFormat :: Regular ) ;
288
+ let mut result = format_result ( results, show_checks) ;
289
+ writeln ! ( result, "Verification Time: {}s" , self . runtime. as_secs_f32( ) ) . unwrap ( ) ;
290
+ result
291
+ }
292
+ Err ( exit_status) => {
293
+ let verification_result = console:: style ( "FAILED" ) . red ( ) ;
294
+ format ! (
295
+ "\n CBMC failed with status {exit_status}\n VERIFICATION:- {verification_result}\n " ,
296
+ )
297
+ }
305
298
}
306
299
}
307
300
308
301
/// Find the failed properties from this verification run
309
302
pub fn failed_properties ( & self ) -> Vec < & Property > {
310
- if let Some ( properties) = & self . results {
303
+ if let Ok ( properties) = & self . results {
311
304
properties. iter ( ) . filter ( |prop| prop. status == CheckStatus :: Failure ) . collect ( )
312
305
} else {
306
+ debug_assert ! ( false , "expected error to be handled before invoking this function" ) ;
313
307
vec ! [ ]
314
308
}
315
309
}
0 commit comments