Resolver: apply type storage class uses via parameters

Bug: tint:185
Bug: tint:682
Change-Id: I0a35d9419af3a74376ef96197bbe99630d54632e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46381
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index bdf95be..f09849c 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -248,6 +248,15 @@
   }
 
   for (auto* param : func->params()) {
+    if (!ApplyStorageClassUsageToType(param->declared_storage_class(),
+                                      param->declared_type(),
+                                      param->source())) {
+      diagnostics_.add_note("while instantiating parameter " +
+                                builder_->Symbols().NameFor(param->symbol()),
+                            param->source());
+      return false;
+    }
+
     if (!ValidateParameter(param)) {
       return false;
     }
diff --git a/src/resolver/struct_storage_class_use_test.cc b/src/resolver/struct_storage_class_use_test.cc
index 34fa7e2..05db907 100644
--- a/src/resolver/struct_storage_class_use_test.cc
+++ b/src/resolver/struct_storage_class_use_test.cc
@@ -36,6 +36,19 @@
   EXPECT_TRUE(sem->StorageClassUsage().empty());
 }
 
+TEST_F(ResolverStorageClassUseTest, StructReachableFromParameter) {
+  auto* s = Structure("S", {Member("a", ty.f32())});
+
+  Func("f", {Var("param", s, ast::StorageClass::kNone)}, ty.void_(), {}, {});
+
+  ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+  auto* sem = Sem().Get(s);
+  ASSERT_NE(sem, nullptr);
+  EXPECT_THAT(sem->StorageClassUsage(),
+              UnorderedElementsAre(ast::StorageClass::kNone));
+}
+
 TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) {
   auto* s = Structure("S", {Member("a", ty.f32())});