diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc index e11384e605..7039fa4b6d 100644 --- a/src/tint/resolver/function_validation_test.cc +++ b/src/tint/resolver/function_validation_test.cc @@ -354,10 +354,19 @@ TEST_F(ResolverFunctionValidationTest, CannotCallEntryPoint) { EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), - R"(12:34 error: entry point functions cannot be the target of a function call)"); } +TEST_F(ResolverFunctionValidationTest, CannotCallFunctionAtModuleScope) { + // fn F() -> i32 { return 1; } + // var x = F(); + Func("F", {}, ty.i32(), {Return(1_i)}); + GlobalVar("x", nullptr, Call(Source{{12, 34}}, "F"), ast::StorageClass::kPrivate); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), R"(12:34 error: functions cannot be called at module-scope)"); +} + TEST_F(ResolverFunctionValidationTest, PipelineStage_MustBeUnique_Fail) { // @fragment // @vertex diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 558cb1253d..a2e7799887 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -1695,6 +1695,11 @@ bool Validator::FunctionCall(const sem::Call* call, sem::Statement* current_stat auto sym = decl->target.name->symbol; auto name = symbols_.NameFor(sym); + if (!current_statement) { // Function call at module-scope. + AddError("functions cannot be called at module-scope", decl->source); + return false; + } + if (target->Declaration()->IsEntryPoint()) { // https://www.w3.org/TR/WGSL/#function-restriction // An entry point must never be the target of a function call.