[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_());