tint: Prevent function calls at module-scope

Bug: chromium:1339723
Bug: tint:1606
Change-Id: Ia2e10d6ac38fde0a9c851d279fe07f50f108546e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/95081
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index e11384e..7039fa4 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -354,10 +354,19 @@
 
     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 558cb12..a2e7799 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -1695,6 +1695,11 @@
     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.