use super::super::{
classify_emit_error, classify_validation_error, is_cfg_structurization_error,
is_cross_binding_pointer_merge_error, is_logical_pointer_phi_error,
is_pointer_typing_emit_error, is_pointer_typing_validation_error, EmitErrorClass,
ValidationClass,
};
fn legacy_validation(err: &str) -> ValidationClass {
if is_pointer_typing_validation_error(err) {
ValidationClass::PointerTyping
} else if is_cfg_structurization_error(err) {
ValidationClass::CfgStructurization
} else if is_logical_pointer_phi_error(err) {
ValidationClass::LogicalPointerPhi
} else if is_cross_binding_pointer_merge_error(err) {
ValidationClass::CrossBindingPointerMerge
} else {
ValidationClass::Other
}
}
fn legacy_emit(err: &str) -> EmitErrorClass {
if is_pointer_typing_emit_error(err) {
EmitErrorClass::PointerTyping
} else {
EmitErrorClass::Other
}
}
const VALIDATION_CASES: &[(&str, ValidationClass)] = &[
(
"error: line 42: OpAccessChain Result Type does not match the type in the base composite; \
result type does not match Pointer type",
ValidationClass::PointerTyping,
),
(
"error: OpStore Pointer type and Object type do not match: does not match Object",
ValidationClass::PointerTyping,
),
(
"OpInBoundsAccessChain reached non-composite type while indexes still remain to be traversed",
ValidationClass::PointerTyping,
),
(
"error: OpInBoundsAccessChain cannot find index 3 in the structure",
ValidationClass::PointerTyping,
),
(
"error: Result Type does not match the type used to index",
ValidationClass::PointerTyping,
),
(
"error: The continue construct with the continue target has invalid back-edge",
ValidationClass::CfgStructurization,
),
(
"error: Block 12 must be structured as a selection construct",
ValidationClass::CfgStructurization,
),
(
"error: Block 7 appears in the binary before its dominator 3",
ValidationClass::CfgStructurization,
),
(
"error: Header block 4 does not strictly dominate its merge block 9",
ValidationClass::CfgStructurization,
),
(
"error: Structured CFG rejected: unstructured back-edge",
ValidationClass::CfgStructurization,
),
(
"error: In Logical addressing OpPhi variable may only have a logical pointer operand",
ValidationClass::LogicalPointerPhi,
),
(
"error: Variable pointers must point into the same structure or elements of the same array",
ValidationClass::CrossBindingPointerMerge,
),
(
"error: some unrelated capability is missing for OpFoo",
ValidationClass::Other,
),
("", ValidationClass::Other),
];
const EMIT_CASES: &[(&str, EmitErrorClass)] = &[
(
"native emitter: reinterpret bit width mismatch: buffer pointee 4 vs load 8",
EmitErrorClass::PointerTyping,
),
(
"native emitter: missing pointer storage for %ptr",
EmitErrorClass::PointerTyping,
),
(
"native emitter: cannot reinterpret load of byte pointer %p to <4 x float>",
EmitErrorClass::PointerTyping,
),
(
"native emitter: cannot reinterpret workgroup pointer %tg",
EmitErrorClass::PointerTyping,
),
(
"native emitter: cannot store through reinterpreted pointer select %sel",
EmitErrorClass::PointerTyping,
),
(
"native emitter: structured cfg rejected for an unstructured back-edge",
EmitErrorClass::Other,
),
(
"native emitter: structured cfg has a non-header merge",
EmitErrorClass::Other,
),
(
"native emitter: unknown callee @air.intersect.f32.i32",
EmitErrorClass::Other,
),
("", EmitErrorClass::Other),
];
#[test]
fn validation_classifier_matches_expected_and_legacy_chain() {
for (msg, expected) in VALIDATION_CASES {
let got = classify_validation_error(msg);
assert_eq!(got, *expected, "classify_validation_error({msg:?})");
assert_eq!(
got,
legacy_validation(msg),
"classifier diverged from the legacy guard chain for {msg:?}"
);
}
}
#[test]
fn emit_classifier_matches_expected_and_legacy_chain() {
for (msg, expected) in EMIT_CASES {
let got = classify_emit_error(msg);
assert_eq!(got, *expected, "classify_emit_error({msg:?})");
assert_eq!(
got,
legacy_emit(msg),
"classifier diverged from the legacy guard chain for {msg:?}"
);
}
}
#[test]
fn precedence_prefers_pointer_typing_over_cfg() {
let both = "does not match Pointer; and also a back-edge violation in the loop header";
assert!(is_pointer_typing_validation_error(both));
assert!(is_cfg_structurization_error(both));
assert_eq!(
classify_validation_error(both),
ValidationClass::PointerTyping
);
assert_eq!(legacy_validation(both), ValidationClass::PointerTyping);
}