[tint][ir][val] Check that entry points have names

Fixes: 356419160
Change-Id: I78a5f7ca62857d66157ed0408498c056208a2d5f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200615
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 0406d33..c45c8ff 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -977,6 +977,12 @@
         AddError(func) << "references are not permitted as return types";
     }
 
+    if (func->Stage() != Function::PipelineStage::kUndefined) {
+        if (TINT_UNLIKELY(mod_.NameOf(func).Name().empty())) {
+            AddError(func) << "entry points must have names";
+        }
+    }
+
     QueueBlock(func->Block());
     ProcessTasks();
 }
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 2b4a95a..248cec3 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -340,6 +340,29 @@
 )");
 }
 
+TEST_F(IR_ValidatorTest, Function_UnnamedEntryPoint) {
+    auto* f = b.Function(ty.void_());
+    f->SetWorkgroupSize(0, 0, 0);
+    f->SetStage(Function::PipelineStage::kCompute);
+
+    b.Append(f->Block(), [&] { b.Return(f); });
+
+    auto res = ir::Validate(mod);
+    ASSERT_NE(res, Success);
+    EXPECT_EQ(res.Failure().reason.Str(),
+              R"(:1:1 error: entry points must have names
+%1 = @compute @workgroup_size(0, 0, 0) func():void {
+^^
+
+note: # Disassembly
+%1 = @compute @workgroup_size(0, 0, 0) func():void {
+  $B1: {
+    ret
+  }
+}
+)");
+}
+
 TEST_F(IR_ValidatorTest, CallToFunctionOutsideModule) {
     auto* f = b.Function("f", ty.void_());
     auto* g = b.Function("g", ty.void_());