Skip to content

Commit a873d32

Browse files
committed
fuzz: Extract FpKind out of the macro
1 parent 96b8d08 commit a873d32

2 files changed

Lines changed: 52 additions & 33 deletions

File tree

fuzz/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ publish = false
77
[dependencies]
88
afl = "0.15.10"
99
clap = { version = "4.1.13", features = ["derive"] }
10+
num-derive = "0.4.2"
1011
num-traits = "0.2.15"
1112
rustc_apfloat = { path = ".." }
1213

fuzz/src/main.rs

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66
mod apf_fuzz;
77
mod exhaustive;
88

9-
use clap::{CommandFactory, Parser, Subcommand};
109
use io::IsTerminal;
11-
use rustc_apfloat::ieee::{Double, Single};
12-
use rustc_apfloat::{Float, FloatConvert, Round, Status, StatusAnd, ieee};
13-
use std::io::{self, Read};
10+
use io::Read;
11+
use std::io;
1412
use std::path::PathBuf;
1513
use std::{fmt, fs};
1614

15+
use clap::{CommandFactory, Parser, Subcommand};
16+
use num_derive::FromPrimitive;
17+
use num_traits::FromPrimitive;
18+
use rustc_apfloat::ieee::{Double, Single};
19+
use rustc_apfloat::{Float, FloatConvert, Round, Status, StatusAnd, ieee};
20+
1721
use crate::apf_fuzz::Op;
1822

1923
#[derive(Clone, Parser, Debug)]
@@ -185,7 +189,6 @@ trait FloatRepr: Copy + Default + Eq + fmt::Display + fmt::Debug {
185189
macro_rules! float_reprs {
186190
($($name:ident($repr:ty) {
187191
type RustcApFloat = $rs_apf_ty:ty;
188-
const REPR_TAG = $repr_tag:expr;
189192
extern fn = $cxx_apf_eval_fuzz_op:ident;
190193
$(type HardFloat = $hard_float_ty:ty;)?
191194
})+) => {
@@ -198,26 +201,6 @@ macro_rules! float_reprs {
198201
};
199202
}
200203

201-
#[allow(non_camel_case_types)]
202-
#[derive(Clone, Copy, Debug, PartialEq)]
203-
enum FpKind {
204-
$($name = $repr_tag,)+
205-
}
206-
207-
impl FpKind {
208-
fn from_u8(tag: u8) -> Option<Self> {
209-
let v = match tag {
210-
$(x if x == Self::$name.to_u8() => Self::$name,)+
211-
_ => return None,
212-
};
213-
Some(v)
214-
}
215-
216-
fn to_u8(self) -> u8 {
217-
self as u8
218-
}
219-
}
220-
221204
$(
222205
#[repr(C)]
223206
#[derive(Copy, Clone, Default, PartialEq, Eq)]
@@ -312,52 +295,76 @@ macro_rules! float_reprs {
312295
float_reprs! {
313296
Ieee16(u16) {
314297
type RustcApFloat = rustc_apfloat::ieee::Half;
315-
const REPR_TAG = 16;
316298
extern fn = cxx_apf_eval_op_ieee16;
317299
}
318300
Ieee32(u32) {
319301
type RustcApFloat = rustc_apfloat::ieee::Single;
320-
const REPR_TAG = 32;
321302
extern fn = cxx_apf_eval_op_ieee32;
322303
type HardFloat = f32;
323304
}
324305
Ieee64(u64) {
325306
type RustcApFloat = rustc_apfloat::ieee::Double;
326-
const REPR_TAG = 64;
327307
extern fn = cxx_apf_eval_op_ieee64;
328308
type HardFloat = f64;
329309
}
330310
Ieee128(u128) {
331311
type RustcApFloat = rustc_apfloat::ieee::Quad;
332-
const REPR_TAG = 128;
333312
extern fn = cxx_apf_eval_op_ieee128;
334313
}
335314

336315
// Non-standard IEEE-like formats.
337316
F8E5M2(u8) {
338317
type RustcApFloat = rustc_apfloat::ieee::Float8E5M2;
339-
const REPR_TAG = 8 + 0;
340318
extern fn = cxx_apf_eval_op_f8e5m2;
341319
}
342320
F8E4M3FN(u8) {
343321
type RustcApFloat = rustc_apfloat::ieee::Float8E4M3FN;
344-
const REPR_TAG = 8 + 1;
345322
extern fn = cxx_apf_eval_op_f8e4m3fn;
346323
}
347324
BrainF16(u16) {
348325
type RustcApFloat = rustc_apfloat::ieee::BFloat;
349-
const REPR_TAG = 16 + 1;
350326
extern fn = cxx_apf_eval_op_brainf16;
351327
}
352328
X87_F80(u128) {
353329
type RustcApFloat = rustc_apfloat::ieee::X87DoubleExtended;
354-
const REPR_TAG = 80;
355330
extern fn = cxx_apf_eval_op_x87_f80;
356331
}
357332
}
358333

359334
pub(crate) use for_each_repr;
360335

336+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FromPrimitive)]
337+
pub enum FpKind {
338+
// The tag is based on the bit count. These are specified so corpus inputs are stable.
339+
Ieee16 = 16,
340+
Ieee32 = 32,
341+
Ieee64 = 64,
342+
Ieee128 = 128,
343+
F8E5M2 = 8,
344+
F8E4M3FN = 8 + 1,
345+
BrainF16 = 16 + 1,
346+
#[allow(non_camel_case_types)]
347+
X87_F80 = 80,
348+
}
349+
350+
impl FpKind {
351+
#[cfg_attr(not(test), expect(unused))]
352+
const ALL: &[Self] = &[
353+
Self::Ieee16,
354+
Self::Ieee32,
355+
Self::Ieee64,
356+
Self::Ieee128,
357+
Self::F8E5M2,
358+
Self::F8E4M3FN,
359+
Self::BrainF16,
360+
Self::X87_F80,
361+
];
362+
363+
pub fn to_u8(self) -> u8 {
364+
self as u8
365+
}
366+
}
367+
361368
/// Errors from improperly formed inputs that cause an exit from the fuzzer but do not raise
362369
/// a test failing error.
363370
#[derive(Clone, Copy, Debug)]
@@ -1343,4 +1350,15 @@ mod tests {
13431350
}
13441351
assert_eq!(exp_mask | qnan_bit_mask, F::RustcApFloat::NAN.to_bits());
13451352
}
1353+
1354+
#[test]
1355+
fn fpkind_all_list() {
1356+
let mut computed = (0u8..=u8::MAX)
1357+
.filter_map(FpKind::from_u8)
1358+
.collect::<Vec<_>>();
1359+
let mut listed = FpKind::ALL.to_vec();
1360+
computed.sort_unstable();
1361+
listed.sort_unstable();
1362+
assert_eq!(computed, listed);
1363+
}
13461364
}

0 commit comments

Comments
 (0)