[ir] Require workgroup pointers to be read_write

Fixes a ClusterFuzz test case.

Fixed: 446831128
Change-Id: I5add19f6b0f5f6be82d839c28d90d299bdcf9c78
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/263036
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
Auto-Submit: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index b2c278b..09c6782 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -2033,6 +2033,13 @@
                     }
                 }
 
+                if (ptr->AddressSpace() == AddressSpace::kWorkgroup) {
+                    if (ptr->Access() != core::Access::kReadWrite) {
+                        diag() << "workgroup pointers must be read_write access";
+                        return false;
+                    }
+                }
+
                 if (ptr->AddressSpace() == AddressSpace::kHandle) {
                     if (!ptr->StoreType()->IsHandle()) {
                         diag() << "the 'handle' address space can only be used for handle types";
diff --git a/src/tint/lang/core/ir/validator_type_test.cc b/src/tint/lang/core/ir/validator_type_test.cc
index 479592e..9862822 100644
--- a/src/tint/lang/core/ir/validator_type_test.cc
+++ b/src/tint/lang/core/ir/validator_type_test.cc
@@ -1308,23 +1308,34 @@
         mod.root_block->Append(v);
     }
 
-    auto pass = true;
+    const char* expected_error = nullptr;
     switch (access) {
         case core::Access::kWrite:
+            if (aspace == AddressSpace::kUniform || aspace == AddressSpace::kHandle) {
+                expected_error = "uniform and handle pointers must be read access";
+            } else if (aspace == AddressSpace::kWorkgroup) {
+                expected_error = "workgroup pointers must be read_write access";
+            }
+            break;
         case core::Access::kReadWrite:
-            pass = aspace != AddressSpace::kUniform && aspace != AddressSpace::kHandle;
+            if (aspace == AddressSpace::kUniform || aspace == AddressSpace::kHandle) {
+                expected_error = "uniform and handle pointers must be read access";
+            }
             break;
         case core::Access::kRead:
+            if (aspace == AddressSpace::kWorkgroup) {
+                expected_error = "workgroup pointers must be read_write access";
+            }
+            break;
         default:
             break;
     }
     auto res = ir::Validate(mod);
-    if (pass) {
+    if (expected_error == nullptr) {
         ASSERT_EQ(res, Success);
     } else {
         ASSERT_NE(res, Success);
-        EXPECT_THAT(res.Failure().reason,
-                    testing::HasSubstr("uniform and handle pointers must be read access"));
+        EXPECT_THAT(res.Failure().reason, testing::HasSubstr(expected_error));
     }
 }