resolver: Reject non-storage runtime-sized arrays

There were several cases where we were not rejecting these which were
leading to ICEs or bad codegen.

Fixed: tint:1248
Change-Id: I7cdf3b74d92b81b1067ad908af423ea0b5442328
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76161
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/resolver/storage_class_validation_test.cc b/src/resolver/storage_class_validation_test.cc
index 4c6799f..f836088 100644
--- a/src/resolver/storage_class_validation_test.cc
+++ b/src/resolver/storage_class_validation_test.cc
@@ -45,6 +45,52 @@
             "the function storage class");
 }
 
+TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArray) {
+  Global(Source{{12, 34}}, "v", ty.array(ty.i32()),
+         ast::StorageClass::kPrivate);
+
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(
+      r()->error(),
+      R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+12:34 note: while instantiating variable v)");
+}
+
+TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArrayInStruct) {
+  auto* s = Structure("S", {Member("m", ty.array(ty.i32()))}, {StructBlock()});
+  Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kPrivate);
+
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(
+      r()->error(),
+      R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+note: while analysing structure member S.m
+12:34 note: while instantiating variable v)");
+}
+
+TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArray) {
+  Global(Source{{12, 34}}, "v", ty.array(ty.i32()),
+         ast::StorageClass::kWorkgroup);
+
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(
+      r()->error(),
+      R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+12:34 note: while instantiating variable v)");
+}
+
+TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArrayInStruct) {
+  auto* s = Structure("S", {Member("m", ty.array(ty.i32()))}, {StructBlock()});
+  Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kWorkgroup);
+
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(
+      r()->error(),
+      R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+note: while analysing structure member S.m
+12:34 note: while instantiating variable v)");
+}
+
 TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
   // var<storage> g : i32;
   Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage,
@@ -170,9 +216,11 @@
          });
 
   ASSERT_FALSE(r()->Resolve());
-  EXPECT_EQ(r()->error(),
-            "56:78 error: structure containing a runtime sized array cannot be "
-            "used as a uniform buffer\n12:34 note: structure is declared here");
+  EXPECT_EQ(
+      r()->error(),
+      R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
+note: while analysing structure member S.m
+56:78 note: while instantiating variable svar)");
 }
 
 TEST_F(ResolverStorageClassValidationTest, UniformBufferBool) {