[tint][ir][val] Prevent ICE on malformed module vars Instead skip including them in ReferencedModuleVars, since this is built during Validator construction. During validation these vars will cause the shader to be rejected. Fixes: 414333404 Change-Id: I5084faa0936ccc21494df2f1c52e36364a89996b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/240814 Auto-Submit: Ryan Harrison <rharrison@chromium.org> Reviewed-by: dan sinclair <dsinclair@chromium.org> Commit-Queue: dan sinclair <dsinclair@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/lang/core/ir/referenced_module_vars.h b/src/tint/lang/core/ir/referenced_module_vars.h index 88eb700..524c13b 100644 --- a/src/tint/lang/core/ir/referenced_module_vars.h +++ b/src/tint/lang/core/ir/referenced_module_vars.h
@@ -94,7 +94,11 @@ } if (auto* var = inst->template As<VarT>()) { if (pred(var)) { - if (!var->Result(0)) { + // One of the locations this class is constructed, is by the validator during + // its own constructor, which means this can run before validation occurs. So + // skipping malformed Vars here, since the validator will reject the shader + // later. + if (!var->Result(0) || var->Results().Length() != 1) { continue; } var->Result()->ForEachUseUnsorted([&](const Usage& use) {
diff --git a/src/tint/lang/core/ir/validator_value_test.cc b/src/tint/lang/core/ir/validator_value_test.cc index d16b491..5190be0 100644 --- a/src/tint/lang/core/ir/validator_value_test.cc +++ b/src/tint/lang/core/ir/validator_value_test.cc
@@ -86,6 +86,21 @@ )")) << res.Failure(); } +TEST_F(IR_ValidatorTest, Var_RootBlock_TooManyResults) { + auto* v = b.Var(ty.ptr(private_, ty.i32())); + v->SetInitializer(b.Constant(0_i)); + v->SetResults(Vector{b.InstructionResult<i32>(), b.InstructionResult<i32>()}); + mod.root_block->Append(v); + + auto res = ir::Validate(mod); + ASSERT_NE(res, Success); + EXPECT_THAT(res.Failure().reason, + testing::HasSubstr(R"(:2:20 error: var: expected exactly 1 results, got 2 + %1:i32, %2:i32 = var 0i + ^^^ +)")) << res.Failure(); +} + TEST_F(IR_ValidatorTest, Var_VoidType) { mod.root_block->Append(b.Var(ty.ptr(private_, ty.void_()))); @@ -135,6 +150,25 @@ )")) << res.Failure(); } +TEST_F(IR_ValidatorTest, Var_Function_TooManyResults) { + auto* f = b.Function("my_func", ty.void_()); + + b.Append(f->Block(), [&] { + auto* v = b.Var<function, i32>(); + v->SetInitializer(b.Constant(0_i)); + v->SetResults(Vector{b.InstructionResult<i32>(), b.InstructionResult<i32>()}); + b.Return(f); + }); + + auto res = ir::Validate(mod); + ASSERT_NE(res, Success); + EXPECT_THAT(res.Failure().reason, + testing::HasSubstr(R"(:3:22 error: var: expected exactly 1 results, got 2 + %2:i32, %3:i32 = var 0i + ^^^ +)")) << res.Failure(); +} + TEST_F(IR_ValidatorTest, Var_Function_NonPtrResult) { auto* f = b.Function("my_func", ty.void_());