[tint][ir][fuzz] Prevent fuzzer from crashing on malformed loads
Fixes: 352528962
Change-Id: I1c150a3cc12a6f3a61ccc69712ad96f1606729a7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/198115
Reviewed-by: James Price <jrprice@google.com>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/lang/core/ir/load.h b/src/tint/lang/core/ir/load.h
index 5a2af5d..7c51aa8 100644
--- a/src/tint/lang/core/ir/load.h
+++ b/src/tint/lang/core/ir/load.h
@@ -41,6 +41,12 @@
/// The offset in Operands() for the from value
static constexpr size_t kFromOperandOffset = 0;
+ /// The fixed number of results returned by this instruction
+ static constexpr size_t kNumResults = 1;
+
+ /// The fixed number of operands used by this instruction
+ static constexpr size_t kNumOperands = 1;
+
/// Constructor (no results, no operands)
Load();
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 2b90745..d3b7ad0 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -1670,7 +1670,9 @@
}
void Validator::CheckLoad(const Load* l) {
- CheckOperandNotNull(l, l->From(), Load::kFromOperandOffset);
+ if (TINT_UNLIKELY(!CheckResultsAndOperands(l, Load::kNumResults, Load::kNumOperands))) {
+ return;
+ }
if (auto* from = l->From()) {
auto* mv = from->Type()->As<core::type::MemoryView>();
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 9c5e4c8..dc96213 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -4677,6 +4677,39 @@
)");
}
+TEST_F(IR_ValidatorTest, Load_MissingResult) {
+ auto* f = b.Function("my_func", ty.void_());
+
+ b.Append(f->Block(), [&] {
+ auto* var = b.Var(ty.ptr<function, i32>());
+ auto* load = mod.allocators.instructions.Create<ir::Load>(nullptr, var->Result(0));
+ load->ClearResults();
+ b.Append(load);
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:4:13 error: load: expected exactly 1 results, got 0
+ undef = load %2
+ ^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+note: # Disassembly
+%my_func = func():void {
+ $B1: {
+ %2:ptr<function, i32, read_write> = var
+ undef = load %2
+ ret
+ }
+}
+)");
+}
+
TEST_F(IR_ValidatorTest, Store_NullTo) {
auto* f = b.Function("my_func", ty.void_());