[wgsl] Check addrspace for param with override-sized array
Instead of a checking the address space for override-sized arrays in
all the places that a pointer can be declared, check the address space
in `ApplyAddressSpaceUsageToType`. This matches how we validate
runtime-sized arrays.
Bug: 449592100
Change-Id: I32793fdbfe40fafe9d0154999f633e1d8600f838
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/265455
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 31fcfa3..0190622 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -4771,6 +4771,15 @@
return false;
}
}
+ if (address_space != core::AddressSpace::kWorkgroup) {
+ if (arr->Count()
+ ->IsAnyOf<sem::NamedOverrideArrayCount, sem::UnnamedOverrideArrayCount>()) {
+ AddError(usage)
+ << "override-sized arrays can only be used in the <workgroup> address space";
+ return false;
+ }
+ }
+
return ApplyAddressSpaceUsageToType(address_space,
const_cast<core::type::Type*>(arr->ElemType()), usage);
}
diff --git a/src/tint/lang/wgsl/resolver/type_validation_test.cc b/src/tint/lang/wgsl/resolver/type_validation_test.cc
index 9199534..b612784 100644
--- a/src/tint/lang/wgsl/resolver/type_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/type_validation_test.cc
@@ -374,9 +374,10 @@
Override("size", Expr(10_i));
GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), "size"), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: 'array' with an 'override' element count can only be used as the store "
- "type of a 'var<workgroup>'");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+note: while instantiating 'var' a)");
}
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_InArray) {
@@ -415,25 +416,29 @@
Decl(Var("a", ty.array(Source{{12, 34}}, ty.f32(), "size"))),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: 'array' with an 'override' element count can only be used as the store "
- "type of a 'var<workgroup>'");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+note: while instantiating 'var' a)");
}
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionLet_Explicit) {
// override size = 10i;
+ // var<workgroup> w : array<f32, size>;
// fn f() {
- // var a : array<f32, size>;
+ // let l : array<f32, size> = a;
// }
Override("size", Expr(10_i));
+ GlobalVar("w", ty.array(ty.f32(), "size"), core::AddressSpace::kWorkgroup);
Func("f", tint::Empty, ty.void_(),
Vector{
- Decl(Var("a", ty.array(Source{{12, 34}}, ty.f32(), "size"))),
+ Decl(Let(Source{{12, 34}}, "a", ty.array(ty.f32(), "size"), Expr("w"))),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: 'array' with an 'override' element count can only be used as the store "
- "type of a 'var<workgroup>'");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+12:34 note: while instantiating 'let a')");
}
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionVar_Implicit) {
@@ -446,12 +451,13 @@
GlobalVar("w", ty.array(ty.f32(), "size"), core::AddressSpace::kWorkgroup);
Func("f", tint::Empty, ty.void_(),
Vector{
- Decl(Var("a", Expr(Source{{12, 34}}, "w"))),
+ Decl(Var(Source{{12, 34}}, "a", Expr(Source{{12, 34}}, "w"))),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: 'array' with an 'override' element count can only be used as the store "
- "type of a 'var<workgroup>'");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+12:34 note: while instantiating 'var' a)");
}
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionLet_Implicit) {
@@ -464,12 +470,13 @@
GlobalVar("w", ty.array(ty.f32(), "size"), core::AddressSpace::kWorkgroup);
Func("f", tint::Empty, ty.void_(),
Vector{
- Decl(Let("a", Expr(Source{{12, 34}}, "w"))),
+ Decl(Let(Source{{12, 34}}, "a", Expr("w"))),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: 'array' with an 'override' element count can only be used as the store "
- "type of a 'var<workgroup>'");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+12:34 note: while instantiating 'let a')");
}
TEST_F(ResolverTypeValidationTest, ArraySize_UnnamedOverride_Equivalence) {
@@ -497,7 +504,34 @@
Func("f", Vector{Param("a", ty.array(Source{{12, 34}}, ty.f32(), "size"))}, ty.void_(),
tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: type of function parameter must be constructible");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+note: while instantiating parameter a)");
+}
+
+TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_PointerParam_Workgroup) {
+ // override size = 10i;
+ // fn f(a : ptr<workgroup, array<f32, size>>) {
+ // }
+ Override("size", Expr(10_i));
+ Func("f", Vector{Param("a", ty.ptr(workgroup, ty.array(Source{{12, 34}}, ty.f32(), "size")))},
+ ty.void_(), tint::Empty);
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_PointerParam_Private) {
+ // override size = 10i;
+ // fn f(a : ptr<private, array<f32, size>>) {
+ // }
+ Override("size", Expr(10_i));
+ Func("f", Vector{Param("a", ty.ptr(private_, ty.array(Source{{12, 34}}, ty.f32(), "size")))},
+ ty.void_(), tint::Empty);
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: override-sized arrays can only be used in the <workgroup> address space
+note: while instantiating ptr<private, array<f32, size>, read_write>)");
}
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_ReturnType) {
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index a88fb2b2..50e06c3 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -735,11 +735,6 @@
bool Validator::LocalVariable(const sem::Variable* local) const {
auto* decl = local->Declaration();
- if (IsArrayWithOverrideCount(local->Type())) {
- RaiseArrayWithOverrideCountError(decl->type ? decl->type->source
- : decl->initializer->source);
- return false;
- }
return Switch(
decl, //
[&](const ast::Var* var) {
@@ -760,12 +755,6 @@
const sem::GlobalVariable* global,
const Hashmap<OverrideId, const sem::Variable*, 8>& override_ids) const {
auto* decl = global->Declaration();
- if (global->AddressSpace() != core::AddressSpace::kWorkgroup &&
- IsArrayWithOverrideCount(global->Type())) {
- RaiseArrayWithOverrideCountError(decl->type ? decl->type->source
- : decl->initializer->source);
- return false;
- }
bool ok = Switch(
decl, //
[&](const ast::Var* var) {