Skip to content

Commit 5d265c7

Browse files
authored
Increase width's width for trace values (rust-lang#2172)
1 parent d968d9b commit 5d265c7

File tree

1 file changed

+74
-1
lines changed

1 file changed

+74
-1
lines changed

kani-driver/src/cbmc_output_parser.rs

+74-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ use std::os::unix::process::ExitStatusExt;
3535
use std::path::PathBuf;
3636
use std::process::{Child, ChildStdout};
3737

38+
const RESULT_ITEM_PREFIX: &str = " {\n \"result\":";
39+
3840
/// A parser item is a top-level unit of output from the CBMC json format.
3941
/// See the parser for more information on how they are processed.
4042
#[derive(Debug, Deserialize)]
@@ -57,6 +59,17 @@ pub enum ParserItem {
5759
},
5860
}
5961

62+
/// Struct that is equivalent to `ParserItem::Result`.
63+
///
64+
/// Note: this struct is only used to provide better error messages when there
65+
/// are issues deserializing a `ParserItem::Result`. See `Parser::parse_item`
66+
/// for more details.
67+
#[allow(unused)]
68+
#[derive(Debug, Deserialize)]
69+
struct ResultStruct {
70+
result: Vec<Property>,
71+
}
72+
6073
/// Struct that represents a single property in the set of CBMC results.
6174
///
6275
/// Note: `reach` is not part of the parsed data, but it's useful to annotate
@@ -285,7 +298,7 @@ pub struct TraceValue {
285298
pub name: String,
286299
pub binary: Option<String>,
287300
pub data: Option<TraceData>,
288-
pub width: Option<u8>,
301+
pub width: Option<u32>,
289302
}
290303

291304
/// Enum that represents a trace data item.
@@ -420,6 +433,25 @@ impl<'a, 'b> Parser<'a, 'b> {
420433
if let Ok(item) = result_item {
421434
return item;
422435
}
436+
// If we failed to parse a `ParserItem::Result` earlier, we will get
437+
// this error message when we attempt to parse it using the complete
438+
// string:
439+
// ```
440+
// thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:
441+
// Error("data did not match any variant of untagged enum ParserItem", line: 0, column: 0)'
442+
// ```
443+
// This error message doesn't provide information about what went wrong
444+
// while parsing due to `ParserItem` being an untagged enum. A more
445+
// informative error message will be produced if we attempt to
446+
// deserialize it into a struct. The attempt will still fail, but it
447+
// shouldn't be hard to debug with that information. The same strategy
448+
// can be used for other `ParserItem` variants, but they're normally
449+
// easier to debug.
450+
if string_without_delimiter.starts_with(RESULT_ITEM_PREFIX) {
451+
let result_item: Result<ResultStruct, _> =
452+
serde_json::from_str(string_without_delimiter);
453+
result_item.unwrap();
454+
}
423455
let complete_string = &self.input_so_far[0..self.input_so_far.len()];
424456
let result_item: Result<ParserItem, _> = serde_json::from_str(complete_string);
425457
result_item.unwrap()
@@ -681,4 +713,45 @@ mod tests {
681713
serde_json::from_str(prop_id_string);
682714
let _prop_id = prop_id_result.unwrap();
683715
}
716+
717+
#[test]
718+
fn check_trace_value_deserialization_works() {
719+
let data = format!(
720+
r#"{{
721+
"binary": "{:0>1000}",
722+
"data": "0",
723+
"name": "integer",
724+
"type": "unsigned __CPROVER_bitvector[960]",
725+
"width": 960
726+
}}"#,
727+
0
728+
);
729+
let trace_value: Result<TraceValue, _> = serde_json::from_str(&data);
730+
assert!(trace_value.is_ok());
731+
}
732+
733+
/// Checks that a valid CBMC "result" item can be deserialized into a
734+
/// `ParserItem` or `ResultStruct`.
735+
#[test]
736+
fn check_result_deserialization_works() {
737+
let data = r#"{
738+
"result": [
739+
{
740+
"description": "assertion failed: 1 > 2",
741+
"property": "long_function_name.assertion.1",
742+
"sourceLocation": {
743+
"column": "16",
744+
"file": "/home/ubuntu/file.rs",
745+
"function": "long_function_name",
746+
"line": "815"
747+
},
748+
"status": "SUCCESS"
749+
}
750+
]
751+
}"#;
752+
let parser_item: Result<ParserItem, _> = serde_json::from_str(&data);
753+
let result_struct: Result<ResultStruct, _> = serde_json::from_str(&data);
754+
assert!(parser_item.is_ok());
755+
assert!(result_struct.is_ok());
756+
}
684757
}

0 commit comments

Comments
 (0)