From d205b716cac39c85255739ecae340637578537be Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Wed, 30 Nov 2022 01:13:35 +0000 Subject: [PATCH] tint/resolver: forbid spelling non-instantiable pointer types Fixed: tint:1553 Change-Id: Ib77777a7142d302fe2d0d083de601f7b5042ad6a Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/111881 Commit-Queue: Ben Clayton Kokoro: Ben Clayton Reviewed-by: David Neto --- .../resolver/address_space_validation_test.cc | 895 ++++++++++++++---- .../host_shareable_validation_test.cc | 37 +- src/tint/resolver/resolver.cc | 28 +- src/tint/resolver/resolver_test_helper.h | 2 +- src/tint/resolver/type_validation_test.cc | 48 +- src/tint/resolver/validator.cc | 36 +- src/tint/resolver/validator.h | 6 + src/tint/resolver/variable_validation_test.cc | 25 +- src/tint/transform/decompose_memory_access.cc | 10 + .../transform/decompose_memory_access_test.cc | 144 +-- .../module_scope_var_to_entry_point_param.cc | 6 +- 11 files changed, 900 insertions(+), 337 deletions(-) diff --git a/src/tint/resolver/address_space_validation_test.cc b/src/tint/resolver/address_space_validation_test.cc index 90467b474f..bc6c4a4937 100644 --- a/src/tint/resolver/address_space_validation_test.cc +++ b/src/tint/resolver/address_space_validation_test.cc @@ -27,7 +27,7 @@ using ::testing::HasSubstr; using ResolverAddressSpaceValidationTest = ResolverTest; -TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableNoAddressSpace_Fail) { +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_NoAddressSpace_Fail) { // var g : f32; GlobalVar(Source{{12, 34}}, "g", ty.f32()); @@ -36,8 +36,16 @@ TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableNoAddressSpace_Fail) { "12:34 error: module-scope 'var' declaration must have a address space"); } -TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableFunctionAddressSpace_Fail) { - // var g : f32; +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NoAddressSpace_Fail) { + // type g = ptr; + Alias("g", ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kUndefined)); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), "12:34 error: ptr missing address space"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_FunctionAddressSpace_Fail) { + // var g : f32; GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::AddressSpace::kFunction); EXPECT_FALSE(r()->Resolve()); @@ -45,301 +53,611 @@ TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableFunctionAddressSpace_Fa "12:34 error: module-scope 'var' must not use address space 'function'"); } -TEST_F(ResolverAddressSpaceValidationTest, Private_RuntimeArray) { - GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::AddressSpace::kPrivate); +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Private_RuntimeArray) { + // var v : array; + GlobalVar(Source{{56, 78}}, "v", ty.array(Source{{12, 34}}, ty.i32()), + ast::AddressSpace::kPrivate); EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -12:34 note: while instantiating 'var' v)"); +56:78 note: while instantiating 'var' v)"); } -TEST_F(ResolverAddressSpaceValidationTest, Private_RuntimeArrayInStruct) { - auto* s = Structure("S", utils::Vector{Member("m", ty.array(ty.i32()))}); - GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kPrivate); +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Private_RuntimeArray) { + // type t : ptr>; + Alias("t", ty.pointer(Source{{56, 78}}, ty.array(Source{{12, 34}}, ty.i32()), + ast::AddressSpace::kPrivate)); EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -note: while analyzing structure member S.m -12:34 note: while instantiating 'var' v)"); +56:78 note: while instantiating ptr, read_write>)"); } -TEST_F(ResolverAddressSpaceValidationTest, Workgroup_RuntimeArray) { - GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::AddressSpace::kWorkgroup); +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Private_RuntimeArrayInStruct) { + // struct S { m : array }; + // var v : S; + Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))}); + GlobalVar(Source{{56, 78}}, "v", ty.type_name("S"), ast::AddressSpace::kPrivate); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + R"(error: runtime-sized arrays can only be used in the address space +12:34 note: while analyzing structure member S.m +56:78 note: while instantiating 'var' v)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Private_RuntimeArrayInStruct) { + // struct S { m : array }; + // type t = ptr; + Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))}); + Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kPrivate)); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + R"(error: runtime-sized arrays can only be used in the address space +12:34 note: while analyzing structure member S.m +note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Workgroup_RuntimeArray) { + // var v : array; + GlobalVar(Source{{56, 78}}, "v", ty.array(Source{{12, 34}}, ty.i32()), + ast::AddressSpace::kWorkgroup); EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -12:34 note: while instantiating 'var' v)"); +56:78 note: while instantiating 'var' v)"); } -TEST_F(ResolverAddressSpaceValidationTest, Workgroup_RuntimeArrayInStruct) { - auto* s = Structure("S", utils::Vector{Member("m", ty.array(ty.i32()))}); - GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kWorkgroup); +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Workgroup_RuntimeArray) { + // type t = ptr>; + Alias("t", ty.pointer(ty.array(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kWorkgroup)); EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -note: while analyzing structure member S.m -12:34 note: while instantiating 'var' v)"); +note: while instantiating ptr, read_write>)"); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferBool) { +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Workgroup_RuntimeArrayInStruct) { + // struct S { m : array }; + // var v : S; + Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))}); + GlobalVar(Source{{56, 78}}, "v", ty.type_name("S"), ast::AddressSpace::kWorkgroup); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + R"(error: runtime-sized arrays can only be used in the address space +12:34 note: while analyzing structure member S.m +56:78 note: while instantiating 'var' v)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Workgroup_RuntimeArrayInStruct) { + // struct S { m : array }; + // type t = ptr; + Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))}); + Alias(Source{{56, 78}}, "t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kWorkgroup)); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + R"(error: runtime-sized arrays can only be used in the address space +12:34 note: while analyzing structure member S.m +note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_Bool) { // var g : bool; - GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::AddressSpace::kStorage, Binding(0_a), - Group(0_a)); + GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), ast::AddressSpace::kStorage, + Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable + R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable 56:78 note: while instantiating 'var' g)"); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferBoolAlias) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_Bool) { + // type t = ptr; + Alias(Source{{56, 78}}, "t", + ty.pointer(ty.bool_(Source{{12, 34}}), ast::AddressSpace::kStorage)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable +note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_BoolAlias) { // type a = bool; - // var g : a; - auto* a = Alias("a", ty.bool_()); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::AddressSpace::kStorage, Binding(0_a), - Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ( - r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable -56:78 note: while instantiating 'var' g)"); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferPointer) { - // var g : ptr; - GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate), + // @binding(0) @group(0) var g : a; + Alias("a", ty.bool_()); + GlobalVar(Source{{56, 78}}, "g", ty.type_name(Source{{12, 34}}, "a"), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'ptr' cannot be used in address space 'storage' as it is non-host-shareable + R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable 56:78 note: while instantiating 'var' g)"); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferIntScalar) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_BoolAlias) { + // type a = bool; + // type t = ptr; + Alias("a", ty.bool_()); + Alias(Source{{56, 78}}, "t", + ty.pointer(ty.type_name(Source{{12, 34}}, "a"), ast::AddressSpace::kStorage)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable +note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_Pointer) { + // var g : ptr; + GlobalVar(Source{{56, 78}}, "g", + ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate), + ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'ptr' cannot be used in address space 'storage' as it is non-host-shareable +56:78 note: while instantiating 'var' g)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_Pointer) { + // type t = ptr>; + Alias("t", ty.pointer(Source{{56, 78}}, + ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate), + ast::AddressSpace::kStorage)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'ptr' cannot be used in address space 'storage' as it is non-host-shareable +56:78 note: while instantiating ptr, read>)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_IntScalar) { // var g : i32; - GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kStorage, Binding(0_a), - Group(0_a)); + GlobalVar("g", ty.i32(), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_IntScalar) { + // type t = ptrResolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_F16) { + // enable f16; // var g : f16; Enable(ast::Extension::kF16); - GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); + GlobalVar("g", ty.f16(), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16Alias) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_F16) { + // enable f16; + // type t = ptr; + Enable(ast::Extension::kF16); + + Alias("t", ty.pointer(ty.f16(), ast::AddressSpace::kStorage)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_F16Alias) { + // enable f16; // type a = f16; // var g : a; Enable(ast::Extension::kF16); - auto* a = Alias("a", ty.f16()); - GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::AddressSpace::kStorage, - Binding(0_a), Group(0_a)); + Alias("a", ty.f16()); + GlobalVar("g", ty.type_name("a"), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF32) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_F16Alias) { + // enable f16; + // type a = f16; + // type t = ptr; + Enable(ast::Extension::kF16); + + Alias("a", ty.f16()); + Alias("t", ty.pointer(ty.type_name("a"), ast::AddressSpace::kStorage)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_VectorF32) { // var g : vec4; - GlobalVar(Source{{56, 78}}, "g", ty.vec4(), ast::AddressSpace::kStorage, Binding(0_a), - Group(0_a)); + GlobalVar("g", ty.vec4(), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_VectorF32) { + // type t = ptr>; + Alias("t", ty.pointer(ty.vec4(), ast::AddressSpace::kStorage)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_VectorF16) { // var g : vec4; Enable(ast::Extension::kF16); - GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of(), 4u), ast::AddressSpace::kStorage, - Binding(0_a), Group(0_a)); + GlobalVar("g", ty.vec(ty.f16(), 4u), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF32) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_VectorF16) { + // type t = ptr>; + Enable(ast::Extension::kF16); + Alias("t", ty.pointer(ty.vec(ty.f16(), 4u), ast::AddressSpace::kStorage)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ArrayF32) { + // struct S{ a : f32 }; // var g : array; - auto* s = Structure("S", utils::Vector{Member("a", ty.f32())}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kStorage, ast::Access::kRead, - Binding(0_a), Group(0_a)); + Structure("S", utils::Vector{Member("a", ty.f32())}); + GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage, + ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ArrayF32) { + // struct S{ a : f32 }; + // type t = ptr>; + Structure("S", utils::Vector{Member("a", ty.f32())}); + Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ArrayF16) { + // enable f16; + // struct S{ a : f16 }; // var g : array; Enable(ast::Extension::kF16); - auto* s = Structure("S", utils::Vector{Member("a", ty.f16())}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kStorage, ast::Access::kRead, - Binding(0_a), Group(0_a)); + Structure("S", utils::Vector{Member("a", ty.f16())}); + GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage, + ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructI32) { - // struct S { x : i32 }; - // var g : S; - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); - GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, - Binding(0_a), Group(0_a)); - - ASSERT_TRUE(r()->Resolve()) << r()->error(); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructI32Aliases) { - // struct S { x : i32 }; - // type a1 = S; - // var g : a1; - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); - auto* a1 = Alias("a1", ty.Of(s)); - auto* a2 = Alias("a2", ty.Of(a1)); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, - Binding(0_a), Group(0_a)); - - ASSERT_TRUE(r()->Resolve()) << r()->error(); -} - -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructF16) { - // struct S { x : f16 }; - // var g : S; +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ArrayF16) { + // enable f16; + // struct S{ a : f16 }; + // type t = ptr>; Enable(ast::Extension::kF16); - auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); - GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), + Structure("S", utils::Vector{Member("a", ty.f16())}); + Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage, + ast::Access::kRead)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_StructI32) { + // struct S { x : i32 }; + // var g : S; + Structure("S", utils::Vector{Member("x", ty.i32())}); + GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructF16Aliases) { - // struct S { x : f16 }; +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_StructI32) { + // struct S { x : i32 }; + // type t = ptr; + Structure("S", utils::Vector{Member("x", ty.i32())}); + Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_StructI32Aliases) { + // struct S { x : i32 }; // type a1 = S; // var g : a1; + Structure("S", utils::Vector{Member("x", ty.i32())}); + Alias("a1", ty.type_name("S")); + Alias("a2", ty.type_name("a1")); + GlobalVar("g", ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_StructI32Aliases) { + // struct S { x : i32 }; + // type a1 = S; + // type t = ptr; + Structure("S", utils::Vector{Member("x", ty.i32())}); + Alias("a1", ty.type_name("S")); + Alias("a2", ty.type_name("a1")); + Alias("t", ty.pointer(ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_StructF16) { + // struct S { x : f16 }; + // var g : S; Enable(ast::Extension::kF16); - auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))}); - auto* a1 = Alias("a1", ty.Of(s)); - auto* a2 = Alias("a2", ty.Of(a1)); - GlobalVar("g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), + Structure("S", utils::Vector{Member("x", ty.f16())}); + GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, NotStorage_AccessMode) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_StructF16) { + // struct S { x : f16 }; + // type t = ptr; + Enable(ast::Extension::kF16); + + Structure("S", utils::Vector{Member("x", ty.f16())}); + Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_StructF16Aliases) { + // struct S { x : f16 }; + // type a1 = S; + // var g : a1; + Enable(ast::Extension::kF16); + + Structure("S", utils::Vector{Member("x", ty.f16())}); + Alias("a1", ty.type_name("S")); + Alias("a2", ty.type_name("a1")); + GlobalVar("g", ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead, + Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_StructF16Aliases) { + // struct S { x : f16 }; + // type a1 = S; + // type t = ptr; + Enable(ast::Extension::kF16); + + Structure("S", utils::Vector{Member("x", ty.f16())}); + Alias("a1", ty.type_name("S")); + Alias("a2", ty.type_name("a1")); + Alias("g", ty.pointer(ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_NotStorage_AccessMode) { // var g : a; - GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead); + GlobalVar(Source{{12, 34}}, "g", ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: only variables in address space may declare an access mode)"); + R"(12:34 error: only variables in address space may declare an access mode)"); } -TEST_F(ResolverAddressSpaceValidationTest, Storage_ReadAccessMode) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NotStorage_AccessMode) { + // type t = ptr; + Alias("t", + ty.pointer(Source{{12, 34}}, ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: only pointers in address space may declare an access mode)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ReadAccessMode) { // @group(0) @binding(0) var a : i32; - GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead, - Group(0_a), Binding(0_a)); + GlobalVar("a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a), + Binding(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, Storage_ReadWriteAccessMode) { - // @group(0) @binding(0) var a : i32; - GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite, - Group(0_a), Binding(0_a)); +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ReadAccessMode) { + // type t = ptr; + Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, Storage_WriteAccessMode) { +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ReadWriteAccessMode) { // @group(0) @binding(0) var a : i32; - GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kWrite, + GlobalVar("a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a), + Binding(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ReadWriteAccessMode) { + // type t = ptr; + Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_WriteAccessMode) { + // @group(0) @binding(0) var a : i32; + GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kWrite, Group(0_a), Binding(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), - R"(56:78 error: access mode 'write' is not valid for the 'storage' address space)"); + R"(12:34 error: access mode 'write' is not valid for the 'storage' address space)"); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBuffer_Struct_Runtime) { - // struct S { m: array; }; - // @group(0) @binding(0) var svar : S; +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_WriteAccessMode) { + // type t = ptr; + Alias("t", + ty.pointer(Source{{12, 34}}, ty.i32(), ast::AddressSpace::kStorage, ast::Access::kWrite)); - auto* s = Structure(Source{{12, 34}}, "S", utils::Vector{Member("m", ty.array())}); + ASSERT_FALSE(r()->Resolve()); - GlobalVar(Source{{56, 78}}, "svar", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + EXPECT_EQ(r()->error(), + R"(12:34 error: access mode 'write' is not valid for the 'storage' address space)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBuffer_Struct_Runtime) { + // struct S { m: array; }; + // @group(0) @binding(0) var svar : S; + + Structure("S", + utils::Vector{Member(Source{{56, 78}}, "m", ty.array(Source{{12, 34}}, ty.i32()))}); + + GlobalVar(Source{{90, 12}}, "svar", ty.type_name("S"), ast::AddressSpace::kUniform, + Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), - R"(56:78 error: runtime-sized arrays can only be used in the address space -note: while analyzing structure member S.m -56:78 note: while instantiating 'var' svar)"); + R"(12:34 error: runtime-sized arrays can only be used in the address space +56:78 note: while analyzing structure member S.m +90:12 note: while instantiating 'var' svar)"); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferBool) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBuffer_Struct_Runtime) { + // struct S { m: array; }; + // type t = ptr; + + Structure("S", + utils::Vector{Member(Source{{56, 78}}, "m", ty.array(Source{{12, 34}}, ty.i32()))}); + + Alias("t", ty.pointer(Source{{90, 12}}, ty.type_name("S"), ast::AddressSpace::kUniform)); + + ASSERT_FALSE(r()->Resolve()); + EXPECT_EQ( + r()->error(), + R"(12:34 error: uniform storage requires that array elements be aligned to 16 bytes, but array element alignment is currently 4. Consider using a vector or struct as the element type instead. +note: see layout of struct: +/* align(4) size(4) */ struct S { +/* offset(0) align(4) size(4) */ m : array; +/* */ }; +90:12 note: 'S' used in address space 'uniform' here)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferBool) { // var g : bool; - GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), ast::AddressSpace::kUniform, + Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable + R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable 56:78 note: while instantiating 'var' g)"); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferBoolAlias) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferBool) { + // type t = ptr; + Alias("t", + ty.pointer(Source{{56, 78}}, ty.bool_(Source{{12, 34}}), ast::AddressSpace::kUniform)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable +56:78 note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferBoolAlias) { // type a = bool; // var g : a; - auto* a = Alias("a", ty.bool_()); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); - - ASSERT_FALSE(r()->Resolve()); - - EXPECT_EQ( - r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable -56:78 note: while instantiating 'var' g)"); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferPointer) { - // var g : ptr; - GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate), + Alias("a", ty.bool_()); + GlobalVar(Source{{56, 78}}, "g", ty.type_name(Source{{12, 34}}, "a"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'ptr' cannot be used in address space 'uniform' as it is non-host-shareable + R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable 56:78 note: while instantiating 'var' g)"); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferIntScalar) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferBoolAlias) { + // type a = bool; + // type t = ptr; + Alias("a", ty.bool_()); + Alias("t", ty.pointer(Source{{56, 78}}, ty.type_name(Source{{12, 34}}, "a"), + ast::AddressSpace::kUniform)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable +56:78 note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformPointer) { + // var g : ptr; + GlobalVar(Source{{56, 78}}, "g", + ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate), + ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'ptr' cannot be used in address space 'uniform' as it is non-host-shareable +56:78 note: while instantiating 'var' g)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformPointer) { + // type t = ptr>; + Alias("t", ty.pointer(Source{{56, 78}}, + ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate), + ast::AddressSpace::kUniform)); + + ASSERT_FALSE(r()->Resolve()); + + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'ptr' cannot be used in address space 'uniform' as it is non-host-shareable +56:78 note: while instantiating ptr, read>)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferIntScalar) { // var g : i32; GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); @@ -347,124 +665,241 @@ TEST_F(ResolverAddressSpaceValidationTest, UniformBufferIntScalar) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferIntScalar) { + // type t = ptr; + Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferF16) { + // enable f16; // var g : f16; Enable(ast::Extension::kF16); - GlobalVar(Source{{56, 78}}, "g", ty.f16(), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + GlobalVar("g", ty.f16(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF32) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferF16) { + // enable f16; + // type t = ptr; + Enable(ast::Extension::kF16); + + Alias("t", ty.pointer(ty.f16(), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferVectorF32) { // var g : vec4; - GlobalVar(Source{{56, 78}}, "g", ty.vec4(), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + GlobalVar("g", ty.vec4(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferVectorF32) { + // type t = ptr>; + Alias("t", ty.pointer(ty.vec4(), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferVectorF16) { + // enable f16; // var g : vec4; Enable(ast::Extension::kF16); - GlobalVar(Source{{56, 78}}, "g", ty.vec4(), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + GlobalVar("g", ty.vec4(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF32) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferVectorF16) { + // enable f16; + // type t = ptr>; + Enable(ast::Extension::kF16); + + Alias("t", ty.pointer(ty.vec4(), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferArrayF32) { // struct S { // @size(16) f : f32; // } // var g : array; - auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); + Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})}); + GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform, Binding(0_a), + Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferArrayF32) { + // struct S { + // @size(16) f : f32; + // } + // type t = ptr>; + Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})}); + Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferArrayF16) { + // enable f16; // struct S { // @size(16) f : f16; // } // var g : array; Enable(ast::Extension::kF16); - auto* s = Structure("S", utils::Vector{Member("a", ty.f16(), utils::Vector{MemberSize(16_a)})}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); - - ASSERT_TRUE(r()->Resolve()) << r()->error(); -} - -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructI32) { - // struct S { x : i32 }; - // var g : S; - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); - GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), + Structure("S", utils::Vector{Member("a", ty.f16(), utils::Vector{MemberSize(16_a)})}); + GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructI32Aliases) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferArrayF16) { + // enable f16; + // struct S { + // @size(16) f : f16; + // } + // type t = ptr>; + Enable(ast::Extension::kF16); + + Structure("S", utils::Vector{Member("a", ty.f16(), utils::Vector{MemberSize(16_a)})}); + Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferStructI32) { + // struct S { x : i32 }; + // var g : S; + Structure("S", utils::Vector{Member("x", ty.i32())}); + GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferStructI32) { + // struct S { x : i32 }; + // type t = ptr; + Structure("S", utils::Vector{Member("x", ty.i32())}); + Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferStructI32Aliases) { // struct S { x : i32 }; // type a1 = S; // var g : a1; - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())}); - auto* a1 = Alias("a1", ty.Of(s)); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + Structure("S", utils::Vector{Member("x", ty.i32())}); + Alias("a1", ty.type_name("S")); + GlobalVar("g", ty.type_name("a1"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferStructI32Aliases) { + // struct S { x : i32 }; + // type a1 = S; + // type t = ptr; + Structure("S", utils::Vector{Member("x", ty.i32())}); + Alias("a1", ty.type_name("S")); + Alias("t", ty.pointer(ty.type_name("a1"), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferStructF16) { + // enable f16; // struct S { x : f16 }; - // var g : S; + // var g : S; Enable(ast::Extension::kF16); - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.f16())}); - GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + Structure("S", utils::Vector{Member("x", ty.f16())}); + GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16Aliases) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferStructF16) { + // enable f16; + // struct S { x : f16 }; + // type t = ptr; + Enable(ast::Extension::kF16); + + Structure("S", utils::Vector{Member("x", ty.f16())}); + Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferStructF16Aliases) { + // enable f16; // struct S { x : f16 }; // type a1 = S; // var g : a1; Enable(ast::Extension::kF16); - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.f16())}); - auto* a1 = Alias("a1", ty.Of(s)); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::AddressSpace::kUniform, Binding(0_a), - Group(0_a)); + Structure("S", utils::Vector{Member("x", ty.f16())}); + Alias("a1", ty.type_name("S")); + GlobalVar("g", ty.type_name("a1"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantBool) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferStructF16Aliases) { + // enable f16; + // struct S { x : f16 }; + // type a1 = S; + // type t = ptr; + Enable(ast::Extension::kF16); + + Structure("S", utils::Vector{Member("x", ty.f16())}); + Alias("a1", ty.type_name("S")); + Alias("t", ty.pointer(ty.type_name("a1"), ast::AddressSpace::kUniform)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantBool) { // enable chromium_experimental_push_constant; // var g : bool; Enable(ast::Extension::kChromiumExperimentalPushConstant); - GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::AddressSpace::kPushConstant); + GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), ast::AddressSpace::kPushConstant); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable + R"(12:34 error: Type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable 56:78 note: while instantiating 'var' g)"); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantF16) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantBool) { // enable chromium_experimental_push_constant; + // type t = ptr; + Enable(ast::Extension::kChromiumExperimentalPushConstant); + Alias(Source{{56, 78}}, "t", + ty.pointer(ty.bool_(Source{{12, 34}}), ast::AddressSpace::kPushConstant)); + + ASSERT_FALSE(r()->Resolve()); + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable +note: while instantiating ptr)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantF16) { // enable f16; + // enable chromium_experimental_push_constant; // var g : f16; Enable(ast::Extension::kF16); Enable(ast::Extension::kChromiumExperimentalPushConstant); @@ -475,21 +910,50 @@ TEST_F(ResolverAddressSpaceValidationTest, PushConstantF16) { "error: using f16 types in 'push_constant' address space is not implemented yet"); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantPointer) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantF16) { + // enable f16; + // enable chromium_experimental_push_constant; + // type t = ptr; + Enable(ast::Extension::kF16); + Enable(ast::Extension::kChromiumExperimentalPushConstant); + Alias("t", ty.pointer(ty.f16(Source{{56, 78}}), ast::AddressSpace::kPushConstant)); + + ASSERT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + "error: using f16 types in 'push_constant' address space is not implemented yet"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantPointer) { // enable chromium_experimental_push_constant; // var g : ptr; Enable(ast::Extension::kChromiumExperimentalPushConstant); - GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate), + GlobalVar(Source{{56, 78}}, "g", + ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate), ast::AddressSpace::kPushConstant); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'ptr' cannot be used in address space 'push_constant' as it is non-host-shareable + R"(12:34 error: Type 'ptr' cannot be used in address space 'push_constant' as it is non-host-shareable 56:78 note: while instantiating 'var' g)"); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantIntScalar) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantPointer) { + // enable chromium_experimental_push_constant; + // type t = ptr>; + Enable(ast::Extension::kChromiumExperimentalPushConstant); + Alias(Source{{56, 78}}, "t", + ty.pointer(ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate), + ast::AddressSpace::kPushConstant)); + + ASSERT_FALSE(r()->Resolve()); + EXPECT_EQ( + r()->error(), + R"(12:34 error: Type 'ptr' cannot be used in address space 'push_constant' as it is non-host-shareable +note: while instantiating ptr, read_write>)"); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantIntScalar) { // enable chromium_experimental_push_constant; // var g : i32; Enable(ast::Extension::kChromiumExperimentalPushConstant); @@ -498,7 +962,16 @@ TEST_F(ResolverAddressSpaceValidationTest, PushConstantIntScalar) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantVectorF32) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantIntScalar) { + // enable chromium_experimental_push_constant; + // type t = ptr; + Enable(ast::Extension::kChromiumExperimentalPushConstant); + Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kPushConstant)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantVectorF32) { // enable chromium_experimental_push_constant; // var g : vec4; Enable(ast::Extension::kChromiumExperimentalPushConstant); @@ -507,29 +980,35 @@ TEST_F(ResolverAddressSpaceValidationTest, PushConstantVectorF32) { ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantArrayF32) { +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantVectorF32) { // enable chromium_experimental_push_constant; - // struct S { a : f32} - // var g : array; + // var g : vec4; Enable(ast::Extension::kChromiumExperimentalPushConstant); - auto* s = Structure("S", utils::Vector{Member("a", ty.f32())}); - auto* a = ty.array(ty.Of(s), 3_u); - GlobalVar("g", a, ast::AddressSpace::kPushConstant); + Alias("t", ty.pointer(ty.vec4(), ast::AddressSpace::kPushConstant)); ASSERT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAddressSpaceValidationTest, PushConstantWithInitializer) { +TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantArrayF32) { // enable chromium_experimental_push_constant; - // var a : u32 = 0u; + // struct S { a : f32} + // var g : array; Enable(ast::Extension::kChromiumExperimentalPushConstant); - GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), ast::AddressSpace::kPushConstant, - Expr(Source{{3u, 4u}}, u32(0))); + Structure("S", utils::Vector{Member("a", ty.f32())}); + GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kPushConstant); - ASSERT_FALSE(r()->Resolve()); - EXPECT_EQ( - r()->error(), - R"(1:2 error: var of address space 'push_constant' cannot have an initializer. var initializers are only supported for the address spacees 'private' and 'function')"); + ASSERT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantArrayF32) { + // enable chromium_experimental_push_constant; + // struct S { a : f32} + // type t = ptr>; + Enable(ast::Extension::kChromiumExperimentalPushConstant); + Structure("S", utils::Vector{Member("a", ty.f32())}); + Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kPushConstant)); + + ASSERT_TRUE(r()->Resolve()) << r()->error(); } } // namespace diff --git a/src/tint/resolver/host_shareable_validation_test.cc b/src/tint/resolver/host_shareable_validation_test.cc index 97519cdb16..325595ccbe 100644 --- a/src/tint/resolver/host_shareable_validation_test.cc +++ b/src/tint/resolver/host_shareable_validation_test.cc @@ -26,49 +26,52 @@ using namespace tint::number_suffixes; // NOLINT using ResolverHostShareableValidationTest = ResolverTest; TEST_F(ResolverHostShareableValidationTest, BoolMember) { - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.bool_())}); + auto* s = + Structure("S", utils::Vector{Member(Source{{56, 78}}, "x", ty.bool_(Source{{12, 34}}))}); - GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, + GlobalVar(Source{{90, 12}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable -12:34 note: while analyzing structure member S.x -56:78 note: while instantiating 'var' g)"); + R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable +56:78 note: while analyzing structure member S.x +90:12 note: while instantiating 'var' g)"); } TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) { - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.vec3())}); + auto* s = Structure( + "S", utils::Vector{Member(Source{{56, 78}}, "x", ty.vec3(Source{{12, 34}}))}); - GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, + GlobalVar(Source{{90, 12}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'vec3' cannot be used in address space 'storage' as it is non-host-shareable -12:34 note: while analyzing structure member S.x -56:78 note: while instantiating 'var' g)"); + R"(12:34 error: Type 'vec3' cannot be used in address space 'storage' as it is non-host-shareable +56:78 note: while analyzing structure member S.x +90:12 note: while instantiating 'var' g)"); } TEST_F(ResolverHostShareableValidationTest, Aliases) { - auto* a1 = Alias("a1", ty.bool_()); - auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.Of(a1))}); + Alias("a1", ty.bool_()); + auto* s = Structure( + "S", utils::Vector{Member(Source{{56, 78}}, "x", ty.type_name(Source{{12, 34}}, "a1"))}); auto* a2 = Alias("a2", ty.Of(s)); - GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, + GlobalVar(Source{{90, 12}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a)); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ( r()->error(), - R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable -12:34 note: while analyzing structure member S.x -56:78 note: while instantiating 'var' g)"); + R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable +56:78 note: while analyzing structure member S.x +90:12 note: while instantiating 'var' g)"); } TEST_F(ResolverHostShareableValidationTest, NestedStructures) { @@ -85,7 +88,7 @@ TEST_F(ResolverHostShareableValidationTest, NestedStructures) { EXPECT_EQ( r()->error(), - R"(9:10 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable + R"(error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable 1:2 note: while analyzing structure member I1.x 3:4 note: while analyzing structure member I2.y 5:6 note: while analyzing structure member I3.z diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index ccabe39834..cf55a1d30d 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -262,7 +262,18 @@ sem::Type* Resolver::Type(const ast::Type* ty) { if (access == ast::Access::kUndefined) { access = DefaultAccessForAddressSpace(t->address_space); } - return builder_->create(el, t->address_space, access); + auto ptr = builder_->create(el, t->address_space, access); + if (!ptr) { + return nullptr; + } + if (!validator_.Pointer(t, ptr)) { + return nullptr; + } + if (!ApplyAddressSpaceUsageToType(t->address_space, el, t->type->source)) { + AddNote("while instantiating " + builder_->FriendlyName(ptr), t->source); + return nullptr; + } + return ptr; } return nullptr; }, @@ -625,7 +636,8 @@ sem::Variable* Resolver::Var(const ast::Var* var, bool is_global) { auto* var_ty = builder_->create(storage_ty, address_space, access); - if (!ApplyAddressSpaceUsageToType(address_space, var_ty, var->source)) { + if (!ApplyAddressSpaceUsageToType(address_space, var_ty, + var->type ? var->type->source : var->source)) { AddNote("while instantiating 'var' " + builder_->Symbols().NameFor(var->symbol), var->source); return nullptr; @@ -727,7 +739,7 @@ sem::Parameter* Resolver::Parameter(const ast::Parameter* param, uint32_t index) return nullptr; } - if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, ty, param->source)) { + if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, ty, param->type->source)) { add_note(); return nullptr; } @@ -3562,12 +3574,14 @@ bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space, str->AddUsage(address_space); for (auto* member : str->Members()) { - if (!ApplyAddressSpaceUsageToType(address_space, const_cast(member->Type()), - usage)) { + auto decl = member->Declaration(); + if (decl && + !ApplyAddressSpaceUsageToType(address_space, const_cast(member->Type()), + decl->type->source)) { std::stringstream err; err << "while analyzing structure member " << sem_.TypeNameOf(str) << "." - << builder_->Symbols().NameFor(member->Declaration()->symbol); - AddNote(err.str(), member->Declaration()->source); + << builder_->Symbols().NameFor(decl->symbol); + AddNote(err.str(), decl->source); return false; } } diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h index d44c9d81df..68a70178a9 100644 --- a/src/tint/resolver/resolver_test_helper.h +++ b/src/tint/resolver/resolver_test_helper.h @@ -608,7 +608,7 @@ struct DataType> { /// @return a new AST alias type static inline const ast::Type* AST(ProgramBuilder& b) { return b.create(DataType::AST(b), ast::AddressSpace::kPrivate, - ast::Access::kReadWrite); + ast::Access::kUndefined); } /// @param b the ProgramBuilder /// @return the semantic aliased type diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc index 59367d0a9e..fe1aa0570f 100644 --- a/src/tint/resolver/type_validation_test.cc +++ b/src/tint/resolver/type_validation_test.cc @@ -321,12 +321,11 @@ TEST_F(ResolverTypeValidationTest, ArraySize_UnderElementCountLimit) { TEST_F(ResolverTypeValidationTest, ArraySize_OverElementCountLimit) { // var a : array; - GlobalVar(Source{{1, 2}}, "a", - ty.array(Source{{12, 34}}, ty.f32(), Expr(Source{{12, 34}}, 65536_a)), + GlobalVar(Source{{56, 78}}, "a", ty.array(Source{{12, 34}}, ty.f32(), Expr(65536_a)), ast::AddressSpace::kPrivate); EXPECT_FALSE(r()->Resolve()); - EXPECT_EQ(r()->error(), R"(1:2 error: array count (65536) must be less than 65536 -1:2 note: while instantiating 'var' a)"); + EXPECT_EQ(r()->error(), R"(12:34 error: array count (65536) must be less than 65536 +56:78 note: while instantiating 'var' a)"); } TEST_F(ResolverTypeValidationTest, ArraySize_StorageBufferLargeArray) { @@ -569,7 +568,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) { /// @vertex // fn func() { var a : array; } - auto* var = Var(Source{{12, 34}}, "a", ty.array()); + auto* var = Var(Source{{56, 78}}, "a", ty.array(Source{{12, 34}}, ty.i32())); Func("func", utils::Empty, ty.void_(), utils::Vector{ @@ -582,7 +581,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) { EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -12:34 note: while instantiating 'var' a)"); +56:78 note: while instantiating 'var' a)"); } TEST_F(ResolverTypeValidationTest, Struct_Member_VectorNoType) { @@ -731,23 +730,24 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) { } TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) { - GlobalVar(Source{{56, 78}}, "g", ty.array(), ast::AddressSpace::kPrivate); + GlobalVar(Source{{56, 78}}, "g", ty.array(Source{{12, 34}}, ty.i32()), + ast::AddressSpace::kPrivate); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), - R"(56:78 error: runtime-sized arrays can only be used in the address space + R"(12:34 error: runtime-sized arrays can only be used in the address space 56:78 note: while instantiating 'var' g)"); } TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) { - auto* v = Var(Source{{56, 78}}, "g", ty.array()); + auto* v = Var(Source{{56, 78}}, "g", ty.array(Source{{12, 34}}, ty.i32())); WrapInFunction(v); ASSERT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), - R"(56:78 error: runtime-sized arrays can only be used in the address space + R"(12:34 error: runtime-sized arrays can only be used in the address space 56:78 note: while instantiating 'var' g)"); } @@ -755,7 +755,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) { // fn func(a : array) {} // @vertex fn main() {} - auto* param = Param(Source{{12, 34}}, "a", ty.array()); + auto* param = Param(Source{{56, 78}}, "a", ty.array(Source{{12, 34}}, ty.i32())); Func("func", utils::Vector{param}, ty.void_(), utils::Vector{ @@ -773,14 +773,14 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) { EXPECT_FALSE(r()->Resolve()) << r()->error(); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -12:34 note: while instantiating parameter a)"); +56:78 note: while instantiating parameter a)"); } -TEST_F(ResolverTypeValidationTest, PtrToRuntimeArrayAsParameter_Fail) { +TEST_F(ResolverTypeValidationTest, PtrToRuntimeArrayAsPointerParameter_Fail) { // fn func(a : ptr>) {} - auto* param = - Param(Source{{12, 34}}, "a", ty.pointer(ty.array(), ast::AddressSpace::kWorkgroup)); + auto* param = Param("a", ty.pointer(Source{{56, 78}}, ty.array(Source{{12, 34}}, ty.i32()), + ast::AddressSpace::kWorkgroup)); Func("func", utils::Vector{param}, ty.void_(), utils::Vector{ @@ -790,7 +790,23 @@ TEST_F(ResolverTypeValidationTest, PtrToRuntimeArrayAsParameter_Fail) { EXPECT_FALSE(r()->Resolve()) << r()->error(); EXPECT_EQ(r()->error(), R"(12:34 error: runtime-sized arrays can only be used in the address space -12:34 note: while instantiating parameter a)"); +56:78 note: while instantiating ptr, read_write>)"); +} + +TEST_F(ResolverTypeValidationTest, PtrToRuntimeArrayAsParameter_Fail) { + // fn func(a : ptr>) {} + + auto* param = Param(Source{{56, 78}}, "a", ty.array(Source{{12, 34}}, ty.i32())); + + Func("func", utils::Vector{param}, ty.void_(), + utils::Vector{ + Return(), + }); + + EXPECT_FALSE(r()->Resolve()) << r()->error(); + EXPECT_EQ(r()->error(), + R"(12:34 error: runtime-sized arrays can only be used in the address space +56:78 note: while instantiating parameter a)"); } TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) { diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 6a64d5a539..70e1de1db8 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -269,6 +269,28 @@ bool Validator::Atomic(const ast::Atomic* a, const sem::Atomic* s) const { return true; } +bool Validator::Pointer(const ast::Pointer* a, const sem::Pointer* s) const { + if (s->AddressSpace() == ast::AddressSpace::kUndefined) { + AddError("ptr missing address space", a->source); + return false; + } + + if (a->access != ast::Access::kUndefined) { + // https://www.w3.org/TR/WGSL/#access-mode-defaults + // When writing a variable declaration or a pointer type in WGSL source: + // * For the storage address space, the access mode is optional, and defaults to read. + // * For other address spaces, the access mode must not be written. + if (a->address_space != ast::AddressSpace::kStorage) { + AddError("only pointers in address space may declare an access mode", + a->source); + return false; + } + } + + return CheckTypeAccessAddressSpace(s->StoreType(), s->Access(), s->AddressSpace(), utils::Empty, + a->source); +} + bool Validator::StorageTexture(const ast::StorageTexture* t) const { switch (t->access) { case ast::Access::kWrite: @@ -355,11 +377,10 @@ bool Validator::VariableInitializer(const ast::Variable* v, default: // https://gpuweb.github.io/gpuweb/wgsl/#var-and-let // Optionally has an initializer expression, if the variable is in the private or - // function address spacees. + // function address spaces. AddError("var of address space '" + utils::ToString(address_space) + - "' cannot have an initializer. var initializers are only " - "supported for the address spacees " - "'private' and 'function'", + "' cannot have an initializer. var initializers are only supported " + "for the address spaces 'private' and 'function'", v->source); return false; } @@ -672,9 +693,10 @@ bool Validator::Var(const sem::Variable* v) const { } if (var->declared_access != ast::Access::kUndefined) { - // https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration - // The access mode always has a default, and except for variables in the storage address - // space, must not be written. + // https://www.w3.org/TR/WGSL/#access-mode-defaults + // When writing a variable declaration or a pointer type in WGSL source: + // * For the storage address space, the access mode is optional, and defaults to read. + // * For other address spaces, the access mode must not be written. if (var->declared_address_space != ast::AddressSpace::kStorage) { AddError("only variables in address space may declare an access mode", var->source); diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h index 5c0188f3de..0f183bbcef 100644 --- a/src/tint/resolver/validator.h +++ b/src/tint/resolver/validator.h @@ -169,6 +169,12 @@ class Validator { /// @returns true on success, false otherwise. bool Atomic(const ast::Atomic* a, const sem::Atomic* s) const; + /// Validates a pointer type + /// @param a the pointer ast node + /// @param s the pointer sem node + /// @returns true on success, false otherwise. + bool Pointer(const ast::Pointer* a, const sem::Pointer* s) const; + /// Validates an assignment /// @param a the assignment statement /// @param rhs_ty the type of the right hand side diff --git a/src/tint/resolver/variable_validation_test.cc b/src/tint/resolver/variable_validation_test.cc index 964c8d9713..cf35e4cbb6 100644 --- a/src/tint/resolver/variable_validation_test.cc +++ b/src/tint/resolver/variable_validation_test.cc @@ -321,16 +321,16 @@ TEST_F(ResolverVariableValidationTest, NonConstructibleType_Atomic) { TEST_F(ResolverVariableValidationTest, NonConstructibleType_RuntimeArray) { auto* s = Structure("S", utils::Vector{ - Member(Source{{56, 78}}, "m", ty.array(ty.i32())), + Member(Source{{12, 34}}, "m", ty.array()), }); - auto* v = Var(Source{{12, 34}}, "v", ty.Of(s)); + auto* v = Var(Source{{56, 78}}, "v", ty.Of(s)); WrapInFunction(v); EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), - R"(12:34 error: runtime-sized arrays can only be used in the address space -56:78 note: while analyzing structure member S.m -12:34 note: while instantiating 'var' v)"); + R"(error: runtime-sized arrays can only be used in the address space +12:34 note: while analyzing structure member S.m +56:78 note: while instantiating 'var' v)"); } TEST_F(ResolverVariableValidationTest, NonConstructibleType_Struct_WithAtomic) { @@ -365,7 +365,7 @@ TEST_F(ResolverVariableValidationTest, InvalidAddressSpaceForInitializer) { EXPECT_EQ(r()->error(), "12:34 error: var of address space 'workgroup' cannot have " "an initializer. var initializers are only supported for the " - "address spacees 'private' and 'function'"); + "address spaces 'private' and 'function'"); } TEST_F(ResolverVariableValidationTest, VectorConstNoType) { @@ -486,5 +486,18 @@ TEST_F(ResolverVariableValidationTest, ConstInitWithOverrideExpr) { 56:78 note: consider changing 'const' to 'let')"); } +TEST_F(ResolverVariableValidationTest, GlobalVariable_PushConstantWithInitializer) { + // enable chromium_experimental_push_constant; + // var a : u32 = 0u; + Enable(ast::Extension::kChromiumExperimentalPushConstant); + GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), ast::AddressSpace::kPushConstant, + Expr(Source{{3u, 4u}}, u32(0))); + + ASSERT_FALSE(r()->Resolve()); + EXPECT_EQ( + r()->error(), + R"(1:2 error: var of address space 'push_constant' cannot have an initializer. var initializers are only supported for the address spaces 'private' and 'function')"); +} + } // namespace } // namespace tint::resolver diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index 3be550ce1f..944797a8c0 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc @@ -466,6 +466,9 @@ struct DecomposeMemoryAccess::State { const sem::VariableUser* var_user) { auto address_space = var_user->Variable()->AddressSpace(); auto access = var_user->Variable()->Access(); + if (address_space != ast::AddressSpace::kStorage) { + access = ast::Access::kUndefined; + } return utils::GetOrCreate( load_funcs, LoadStoreKey{address_space, access, buf_ty, el_ty}, [&] { utils::Vector params{ @@ -562,6 +565,9 @@ struct DecomposeMemoryAccess::State { const sem::VariableUser* var_user) { auto address_space = var_user->Variable()->AddressSpace(); auto access = var_user->Variable()->Access(); + if (address_space != ast::AddressSpace::kStorage) { + access = ast::Access::kUndefined; + } return utils::GetOrCreate( store_funcs, LoadStoreKey{address_space, access, buf_ty, el_ty}, [&] { utils::Vector params{ @@ -670,7 +676,11 @@ struct DecomposeMemoryAccess::State { const sem::Builtin* intrinsic, const sem::VariableUser* var_user) { auto op = intrinsic->Type(); + auto address_space = var_user->Variable()->AddressSpace(); auto access = var_user->Variable()->Access(); + if (address_space != ast::AddressSpace::kStorage) { + access = ast::Access::kUndefined; + } return utils::GetOrCreate(atomic_funcs, AtomicKey{access, buf_ty, el_ty, op}, [&] { // The first parameter to all WGSL atomics is the expression to the // atomic. This is replaced with two parameters: the buffer and offset. diff --git a/src/tint/transform/decompose_memory_access_test.cc b/src/tint/transform/decompose_memory_access_test.cc index ac798e07d0..4c2cd1145f 100644 --- a/src/tint/transform/decompose_memory_access_test.cc +++ b/src/tint/transform/decompose_memory_access_test.cc @@ -804,126 +804,126 @@ struct UB { @group(0) @binding(0) var ub : UB; @internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 @internal(intrinsic_load_uniform_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 @internal(intrinsic_load_uniform_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 @internal(intrinsic_load_uniform_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_uniform_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec2_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec3_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec3_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 @internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 @internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 @internal(intrinsic_load_uniform_vec4_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { return mat2x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { return mat3x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); } -fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { return mat4x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u))); } -fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); } -fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); } -fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { return mat2x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u))); } -fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u))); } -fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { return mat2x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u))); } -fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { return mat3x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u))); } -fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u))); } -fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { return mat3x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u))); } -fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { return mat4x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u)), tint_symbol_7(buffer, (offset + 12u))); } -fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 24u))); } -fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { return mat4x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u)), tint_symbol_15(buffer, (offset + 24u))); } -fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; for(var i = 0u; (i < 2u); i = (i + 1u)) { arr[i] = tint_symbol_8(buffer, (offset + (i * 16u))); @@ -931,7 +931,7 @@ fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr return arr; } -fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr_1 : array, 2u>; for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { arr_1[i_1] = tint_symbol_31(buffer, (offset + (i_1 * 16u))); @@ -1075,126 +1075,126 @@ struct UB { enable f16; @internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 +fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f32 @internal(intrinsic_load_uniform_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 +fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> i32 @internal(intrinsic_load_uniform_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 +fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> u32 @internal(intrinsic_load_uniform_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 +fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> f16 @internal(intrinsic_load_uniform_vec2_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec2_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 +fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec2 @internal(intrinsic_load_uniform_vec3_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec3_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 +fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec3 @internal(intrinsic_load_uniform_vec4_f32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 @internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 @internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 @internal(intrinsic_load_uniform_vec4_f16) @internal(disable_validation__function_has_no_body) -fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 +fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> vec4 -fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { +fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { return mat2x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u))); } -fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u))); } -fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { +fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { return mat2x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u))); } -fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { +fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { return mat3x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u))); } -fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u))); } -fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { +fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { return mat3x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u))); } -fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { +fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { return mat4x2(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)), tint_symbol_4(buffer, (offset + 16u)), tint_symbol_4(buffer, (offset + 24u))); } -fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)), tint_symbol_8(buffer, (offset + 32u)), tint_symbol_8(buffer, (offset + 48u))); } -fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { +fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { return mat4x4(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)), tint_symbol_12(buffer, (offset + 32u)), tint_symbol_12(buffer, (offset + 48u))); } -fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { +fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x2 { return mat2x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u))); } -fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { +fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x3 { return mat2x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u))); } -fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { +fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat2x4 { return mat2x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u))); } -fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { +fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x2 { return mat3x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u))); } -fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { +fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x3 { return mat3x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u))); } -fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { +fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat3x4 { return mat3x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u))); } -fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { +fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x2 { return mat4x2(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)), tint_symbol_7(buffer, (offset + 8u)), tint_symbol_7(buffer, (offset + 12u))); } -fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { +fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x3 { return mat4x3(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)), tint_symbol_11(buffer, (offset + 16u)), tint_symbol_11(buffer, (offset + 24u))); } -fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { +fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> mat4x4 { return mat4x4(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)), tint_symbol_15(buffer, (offset + 16u)), tint_symbol_15(buffer, (offset + 24u))); } -fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr : array, 2u>; for(var i = 0u; (i < 2u); i = (i + 1u)) { arr[i] = tint_symbol_8(buffer, (offset + (i * 16u))); @@ -1202,7 +1202,7 @@ fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr return arr; } -fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { +fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr, offset : u32) -> array, 2u> { var arr_1 : array, 2u>; for(var i_1 = 0u; (i_1 < 2u); i_1 = (i_1 + 1u)) { arr_1[i_1] = tint_symbol_31(buffer, (offset + (i_1 * 16u))); diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc index 8a69bd327e..9c9c42fb3f 100644 --- a/src/tint/transform/module_scope_var_to_entry_point_param.cc +++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc @@ -139,7 +139,7 @@ struct ModuleScopeVarToEntryPointParam::State { } case ast::AddressSpace::kStorage: case ast::AddressSpace::kUniform: { - // Variables into the Storage and Uniform address spacees are redeclared as entry + // Variables into the Storage and Uniform address spaces are redeclared as entry // point parameters with a pointer type. auto attributes = ctx.Clone(var->Declaration()->attributes); attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter)); @@ -192,7 +192,7 @@ struct ModuleScopeVarToEntryPointParam::State { [[fallthrough]]; } case ast::AddressSpace::kPrivate: { - // Variables in the Private and Workgroup address spacees are redeclared at function + // Variables in the Private and Workgroup address spaces are redeclared at function // scope. Disable address space validation on this variable. auto* disable_validation = ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace); @@ -497,7 +497,7 @@ struct ModuleScopeVarToEntryPointParam::State { } } - // Now remove all module-scope variables with these address spacees. + // Now remove all module-scope variables with these address spaces. for (auto* var_ast : ctx.src->AST().GlobalVariables()) { auto* var_sem = ctx.src->Sem().Get(var_ast); if (var_sem->AddressSpace() != ast::AddressSpace::kNone) {