[tint][ir][val] Reject duplicate entry point names
Fixes: 381906257
Change-Id: If7ad29bd668bf3f590df9886d63d675e59c4d887
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/217715
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/transform/single_entry_point_test.cc b/src/tint/lang/core/ir/transform/single_entry_point_test.cc
index 650cb92..10f2ab9 100644
--- a/src/tint/lang/core/ir/transform/single_entry_point_test.cc
+++ b/src/tint/lang/core/ir/transform/single_entry_point_test.cc
@@ -100,28 +100,6 @@
EXPECT_DEATH_IF_SUPPORTED({ Run(SingleEntryPoint, "foo"); }, "internal compiler error");
}
-TEST_F(IR_SingleEntryPointTest, MultipleEntryPointsMatch) {
- EntryPoint("main");
- EntryPoint("main");
-
- auto* src = R"(
-%main = @fragment func():void {
- $B1: {
- ret
- }
-}
-%main_1 = @fragment func():void { # %main_1: 'main'
- $B2: {
- ret
- }
-}
-)";
-
- EXPECT_EQ(src, str());
-
- EXPECT_DEATH_IF_SUPPORTED({ Run(SingleEntryPoint, "main"); }, "internal compiler error");
-}
-
TEST_F(IR_SingleEntryPointTest, NoChangesNeeded) {
EntryPoint("main");
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index ba45fbd..4d789b9 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -1316,6 +1316,7 @@
Hashset<const ir::Discard*, 4> discards_;
core::ir::ReferencedModuleVars<const Module> referenced_module_vars_;
Hashset<OverrideId, 8> seen_override_ids_;
+ Hashset<std::string, 4> entry_point_names_;
Hashset<ValidatedType, 16> validated_types_{};
};
@@ -1893,6 +1894,14 @@
scope_stack_.Push();
TINT_DEFER(scope_stack_.Pop());
+ // Checking the name early, so its usage can be recorded, even if the function is malformed.
+ if (func->Stage() != Function::PipelineStage::kUndefined) {
+ const auto name = mod_.NameOf(func).Name();
+ if (!entry_point_names_.Add(name)) {
+ AddError(func) << "entry point name " << style::Function(name) << " is not unique";
+ }
+ }
+
if (!func->Type() || !func->Type()->Is<core::type::Function>()) {
AddError(func) << "functions must have type '<function>'";
return;
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 04381bb..74cf423 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -318,6 +318,34 @@
)");
}
+TEST_F(IR_ValidatorTest, Function_DuplicateEntryPointNames) {
+ auto* c = ComputeEntryPoint("dup");
+ c->Block()->Append(b.Return(c));
+
+ auto* f = FragmentEntryPoint("dup");
+ f->Block()->Append(b.Return(f));
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:6:1 error: entry point name 'dup' is not unique
+%dup_1 = @fragment func():void { # %dup_1: 'dup'
+^^^^^^
+
+note: # Disassembly
+%dup = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ ret
+ }
+}
+%dup_1 = @fragment func():void { # %dup_1: 'dup'
+ $B2: {
+ ret
+ }
+}
+)");
+}
+
TEST_F(IR_ValidatorTest, Function_MultinBlock) {
auto* f = b.Function("my_func", ty.void_());
f->SetBlock(b.MultiInBlock());