Skip to content

Commit 11f0b00

Browse files
authored
cranelift: Build a runtest case from fuzzer TestCase's (#4590)
* cranelift: Build a runtest case from fuzzer TestCase's * cranelift: Add a default expected output for a fuzzgen case
1 parent 597eb6f commit 11f0b00

1 file changed

Lines changed: 54 additions & 1 deletion

File tree

cranelift/fuzzgen/src/lib.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,73 @@ use cranelift::codegen::ir::Function;
88
use cranelift::codegen::Context;
99
use cranelift::prelude::*;
1010
use cranelift_native::builder_with_options;
11+
use std::fmt;
1112

1213
mod config;
1314
mod function_generator;
1415

1516
pub type TestCaseInput = Vec<DataValue>;
1617

17-
#[derive(Debug)]
1818
pub struct TestCase {
1919
pub func: Function,
2020
/// Generate multiple test inputs for each test case.
2121
/// This allows us to get more coverage per compilation, which may be somewhat expensive.
2222
pub inputs: Vec<TestCaseInput>,
2323
}
2424

25+
impl fmt::Debug for TestCase {
26+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27+
write!(
28+
f,
29+
r#";; Fuzzgen test case
30+
31+
test interpret
32+
test run
33+
set enable_llvm_abi_extensions
34+
target aarch64
35+
target s390x
36+
target x86_64
37+
38+
"#
39+
)?;
40+
41+
writeln!(f, "{}", self.func)?;
42+
43+
writeln!(f, "; Note: the results in the below test cases are simply a placeholder and probably will be wrong\n")?;
44+
45+
for input in self.inputs.iter() {
46+
// TODO: We don't know the expected outputs, maybe we can run the interpreter
47+
// here to figure them out? Should work, however we need to be careful to catch
48+
// panics in case its the interpreter that is failing.
49+
// For now create a placeholder output consisting of the zero value for the type
50+
let returns = &self.func.signature.returns;
51+
let placeholder_output = returns
52+
.iter()
53+
.map(|param| DataValue::read_from_slice(&[0; 16][..], param.value_type))
54+
.map(|val| format!("{}", val))
55+
.collect::<Vec<_>>()
56+
.join(", ");
57+
58+
// If we have no output, we don't need the == condition
59+
let test_condition = match returns.len() {
60+
0 => String::new(),
61+
1 => format!(" == {}", placeholder_output),
62+
_ => format!(" == [{}]", placeholder_output),
63+
};
64+
65+
let args = input
66+
.iter()
67+
.map(|val| format!("{}", val))
68+
.collect::<Vec<_>>()
69+
.join(", ");
70+
71+
writeln!(f, "; run: {}({}){}", self.func.name, args, test_condition)?;
72+
}
73+
74+
Ok(())
75+
}
76+
}
77+
2578
impl<'a> Arbitrary<'a> for TestCase {
2679
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
2780
FuzzGen::new(u)

0 commit comments

Comments
 (0)