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 <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/tint/resolver/address_space_validation_test.cc b/src/tint/resolver/address_space_validation_test.cc
index 90467b4..bc6c4a4 100644
--- a/src/tint/resolver/address_space_validation_test.cc
+++ b/src/tint/resolver/address_space_validation_test.cc
@@ -27,7 +27,7 @@
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 @@
"12:34 error: module-scope 'var' declaration must have a address space");
}
-TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableFunctionAddressSpace_Fail) {
- // var<function> g : f32;
+TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NoAddressSpace_Fail) {
+ // type g = ptr<f32>;
+ 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<private> g : f32;
GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::AddressSpace::kFunction);
EXPECT_FALSE(r()->Resolve());
@@ -45,301 +53,611 @@
"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<private> v : array<i32>;
+ 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 <storage> 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<private, array<i32>>;
+ 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 <storage> address space
-note: while analyzing structure member S.m
-12:34 note: while instantiating 'var' v)");
+56:78 note: while instantiating ptr<private, array<i32>, 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<i32> };
+ // var<private> 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 <storage> 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<i32> };
+ // type t = ptr<private, S>;
+ 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 <storage> address space
+12:34 note: while analyzing structure member S.m
+note: while instantiating ptr<private, S, read_write>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Workgroup_RuntimeArray) {
+ // var<workgroup> v : array<i32>;
+ 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 <storage> 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<workgroup, array<i32>>;
+ 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 <storage> address space
-note: while analyzing structure member S.m
-12:34 note: while instantiating 'var' v)");
+note: while instantiating ptr<workgroup, array<i32>, read_write>)");
}
-TEST_F(ResolverAddressSpaceValidationTest, StorageBufferBool) {
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Workgroup_RuntimeArrayInStruct) {
+ // struct S { m : array<i32> };
+ // var<workgroup> 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 <storage> 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<i32> };
+ // type t = ptr<workgroup, S>;
+ 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 <storage> address space
+12:34 note: while analyzing structure member S.m
+note: while instantiating ptr<workgroup, S, read_write>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_Bool) {
// var<storage> 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<storage, bool>;
+ 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<storage, bool, read>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_BoolAlias) {
// type a = bool;
- // var<storage, read> 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<storage> g : ptr<private, f32>;
- GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate),
+ // @binding(0) @group(0) var<storage, read> 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<private, f32, read_write>' 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<storage, a>;
+ 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<storage, bool, read>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_Pointer) {
+ // var<storage> g : ptr<private, f32>;
+ 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<private, f32, read_write>' 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<storage, ptr<private, f32>>;
+ 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<private, f32, read_write>' cannot be used in address space 'storage' as it is non-host-shareable
+56:78 note: while instantiating ptr<storage, ptr<private, f32, read_write>, read>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_IntScalar) {
// var<storage> 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 = ptr<storage, i32;
+ Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kStorage));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_F16) {
+ // enable f16;
// var<storage> 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<storage, f16>;
+ 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<storage, read> 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<storage, a>;
+ 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<storage> g : vec4<f32>;
- GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::AddressSpace::kStorage, Binding(0_a),
- Group(0_a));
+ GlobalVar("g", ty.vec4<f32>(), 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<storage, vec4<f32>>;
+ Alias("t", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kStorage));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_VectorF16) {
// var<storage> g : vec4<f16>;
Enable(ast::Extension::kF16);
- GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 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<storage, vec4<f16>>;
+ 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<storage, read> g : array<S, 3u>;
- 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<storage, array<S, 3u>>;
+ 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<storage, read> g : array<S, 3u>;
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<storage, read> 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<storage, read> 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<storage, read> g : S;
+TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ArrayF16) {
+ // enable f16;
+ // struct S{ a : f16 };
+ // type t = ptr<storage, read, array<S, 3u>>;
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<storage, read> 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<storage, read, S>;
+ 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<storage, read> 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<storage, read, a1>;
+ 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<storage, read> 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<storage, read, S>;
+ 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<storage, read> 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<storage, read, 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"));
+ 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<private, read> 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 <storage> address space may declare an access mode)");
+ R"(12:34 error: only variables in <storage> address space may declare an access mode)");
}
-TEST_F(ResolverAddressSpaceValidationTest, Storage_ReadAccessMode) {
+TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NotStorage_AccessMode) {
+ // type t = ptr<private, read, a>;
+ 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 <storage> address space may declare an access mode)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ReadAccessMode) {
// @group(0) @binding(0) var<storage, read> 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<storage, read_write> 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<storage, read, i32>;
+ 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<storage, read_write> 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<storage, read_write, i32>;
+ 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<storage, read_write> 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<f32>; };
- // @group(0) @binding(0) var<uniform, > svar : S;
+TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_WriteAccessMode) {
+ // type t = ptr<storage, read_write, i32>;
+ 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<i32>())});
+ 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<f32>; };
+ // @group(0) @binding(0) var<uniform> 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 <storage> 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 <storage> 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<f32>; };
+ // type t = ptr<uniform, S>;
+
+ 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<i32>;
+/* */ };
+90:12 note: 'S' used in address space 'uniform' here)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferBool) {
// var<uniform> 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<uniform, bool>;
+ 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<uniform, bool, read>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferBoolAlias) {
// type a = bool;
// var<uniform> 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<uniform> g : ptr<private, f32>;
- 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<private, f32, read_write>' 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<uniform, a>;
+ 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<uniform, bool, read>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformPointer) {
+ // var<uniform> g : ptr<private, f32>;
+ 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<private, f32, read_write>' 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<uniform, ptr<private, f32>>;
+ 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<private, f32, read_write>' cannot be used in address space 'uniform' as it is non-host-shareable
+56:78 note: while instantiating ptr<uniform, ptr<private, f32, read_write>, read>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferIntScalar) {
// var<uniform> g : i32;
GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kUniform, Binding(0_a),
Group(0_a));
@@ -347,124 +665,241 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16) {
+TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferIntScalar) {
+ // type t = ptr<uniform, i32>;
+ Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kUniform));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferF16) {
+ // enable f16;
// var<uniform> 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<uniform, f16>;
+ 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<uniform> g : vec4<f32>;
- GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::AddressSpace::kUniform, Binding(0_a),
- Group(0_a));
+ GlobalVar("g", ty.vec4<f32>(), 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<uniform, vec4<f32>>;
+ Alias("t", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kUniform));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferVectorF16) {
+ // enable f16;
// var<uniform> g : vec4<f16>;
Enable(ast::Extension::kF16);
- GlobalVar(Source{{56, 78}}, "g", ty.vec4<f16>(), ast::AddressSpace::kUniform, Binding(0_a),
- Group(0_a));
+ GlobalVar("g", ty.vec4<f16>(), 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<uniform, vec4<f16>>;
+ Enable(ast::Extension::kF16);
+
+ Alias("t", ty.pointer(ty.vec4<f16>(), ast::AddressSpace::kUniform));
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferArrayF32) {
// struct S {
// @size(16) f : f32;
// }
// var<uniform> g : array<S, 3u>;
- 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<uniform, array<S, 3u>>;
+ 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<uniform> g : array<S, 3u>;
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<uniform> 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<uniform, array<S, 3u>>;
+ 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<uniform> 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<uniform, S>;
+ 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<uniform> 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<uniform, a1>;
+ 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<uniform> g : S;
+ // var<uniform> 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<uniform, S>;
+ 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<uniform> 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<uniform, a1>;
+ 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<push_constant> 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<push_constant, bool>;
+ 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<push_constant, bool, read_write>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantF16) {
// enable f16;
+ // enable chromium_experimental_push_constant;
// var<push_constant> g : f16;
Enable(ast::Extension::kF16);
Enable(ast::Extension::kChromiumExperimentalPushConstant);
@@ -475,21 +910,50 @@
"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<push_constant, f16>;
+ 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<push_constant> g : ptr<private, f32>;
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<private, f32, read_write>' cannot be used in address space 'push_constant' as it is non-host-shareable
+ R"(12:34 error: Type 'ptr<private, f32, read_write>' 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<push_constant, ptr<private, f32>>;
+ 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<private, f32, read_write>' cannot be used in address space 'push_constant' as it is non-host-shareable
+note: while instantiating ptr<push_constant, ptr<private, f32, read_write>, read_write>)");
+}
+
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantIntScalar) {
// enable chromium_experimental_push_constant;
// var<push_constant> g : i32;
Enable(ast::Extension::kChromiumExperimentalPushConstant);
@@ -498,7 +962,16 @@
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverAddressSpaceValidationTest, PushConstantVectorF32) {
+TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantIntScalar) {
+ // enable chromium_experimental_push_constant;
+ // type t = ptr<push_constant, i32>;
+ 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<push_constant> g : vec4<f32>;
Enable(ast::Extension::kChromiumExperimentalPushConstant);
@@ -507,29 +980,35 @@
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<push_constant> g : array<S, 3u>;
+ // var<push_constant> g : vec4<f32>;
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<f32>(), ast::AddressSpace::kPushConstant));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverAddressSpaceValidationTest, PushConstantWithInitializer) {
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantArrayF32) {
// enable chromium_experimental_push_constant;
- // var<push_constant> a : u32 = 0u;
+ // struct S { a : f32}
+ // var<push_constant> g : array<S, 3u>;
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<push_constant, array<S, 3u>>;
+ 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 97519cd..325595c 100644
--- a/src/tint/resolver/host_shareable_validation_test.cc
+++ b/src/tint/resolver/host_shareable_validation_test.cc
@@ -26,49 +26,52 @@
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<bool>())});
+ auto* s = Structure(
+ "S", utils::Vector{Member(Source{{56, 78}}, "x", ty.vec3<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 'vec3<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 'vec3<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, 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 @@
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 ccabe39..cf55a1d 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -262,7 +262,18 @@
if (access == ast::Access::kUndefined) {
access = DefaultAccessForAddressSpace(t->address_space);
}
- return builder_->create<sem::Pointer>(el, t->address_space, access);
+ auto ptr = builder_->create<sem::Pointer>(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 @@
auto* var_ty = builder_->create<sem::Reference>(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 @@
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 @@
str->AddUsage(address_space);
for (auto* member : str->Members()) {
- if (!ApplyAddressSpaceUsageToType(address_space, const_cast<sem::Type*>(member->Type()),
- usage)) {
+ auto decl = member->Declaration();
+ if (decl &&
+ !ApplyAddressSpaceUsageToType(address_space, const_cast<sem::Type*>(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 d44c9d8..68a7017 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -608,7 +608,7 @@
/// @return a new AST alias type
static inline const ast::Type* AST(ProgramBuilder& b) {
return b.create<ast::Pointer>(DataType<T>::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 59367d0..fe1aa05 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_OverElementCountLimit) {
// var<private> a : array<f32, 65536>;
- 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 @@
/// @vertex
// fn func() { var a : array<i32>; }
- auto* var = Var(Source{{12, 34}}, "a", ty.array<i32>());
+ 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 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> 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, RuntimeArrayAsGlobalVariable) {
- GlobalVar(Source{{56, 78}}, "g", ty.array<i32>(), 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 <storage> address space
+ R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
56:78 note: while instantiating 'var' g)");
}
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) {
- auto* v = Var(Source{{56, 78}}, "g", ty.array<i32>());
+ 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 <storage> address space
+ R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
56:78 note: while instantiating 'var' g)");
}
@@ -755,7 +755,7 @@
// fn func(a : array<u32>) {}
// @vertex fn main() {}
- auto* param = Param(Source{{12, 34}}, "a", ty.array<i32>());
+ 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 @@
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> 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<workgroup, array<u32>>) {}
- auto* param =
- Param(Source{{12, 34}}, "a", ty.pointer(ty.array<i32>(), 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 @@
EXPECT_FALSE(r()->Resolve()) << r()->error();
EXPECT_EQ(r()->error(),
R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
-12:34 note: while instantiating parameter a)");
+56:78 note: while instantiating ptr<workgroup, array<i32>, read_write>)");
+}
+
+TEST_F(ResolverTypeValidationTest, PtrToRuntimeArrayAsParameter_Fail) {
+ // fn func(a : ptr<workgroup, array<u32>>) {}
+
+ 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 <storage> 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 6a64d5a..70e1de1 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -269,6 +269,28 @@
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 <storage> 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 @@
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 @@
}
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 <storage> address space may declare an access mode",
var->source);
diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h
index 5c0188f..0f183bb 100644
--- a/src/tint/resolver/validator.h
+++ b/src/tint/resolver/validator.h
@@ -169,6 +169,12 @@
/// @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 964c8d9..cf35e4c 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_RuntimeArray) {
auto* s = Structure("S", utils::Vector{
- Member(Source{{56, 78}}, "m", ty.array(ty.i32())),
+ Member(Source{{12, 34}}, "m", ty.array<i32>()),
});
- 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 <storage> 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 <storage> 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 @@
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 @@
56:78 note: consider changing 'const' to 'let')");
}
+TEST_F(ResolverVariableValidationTest, GlobalVariable_PushConstantWithInitializer) {
+ // enable chromium_experimental_push_constant;
+ // var<push_constant> 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 3be550c..944797a 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -466,6 +466,9 @@
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 @@
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 @@
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 ac798e0..4c2cd11 100644
--- a/src/tint/transform/decompose_memory_access_test.cc
+++ b/src/tint/transform/decompose_memory_access_test.cc
@@ -804,126 +804,126 @@
@group(0) @binding(0) var<uniform> ub : UB;
@internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> f32
+fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> i32
+fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> u32
+fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> f16
+fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> vec2<f32>
+fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<f32>
@internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec2<i32>
+fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<i32>
@internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec2<u32>
+fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<u32>
@internal(intrinsic_load_uniform_vec2_f16) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec2<f16>
+fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<f16>
@internal(intrinsic_load_uniform_vec3_f32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<f32>
+fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<f32>
@internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<i32>
+fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<i32>
@internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<u32>
+fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<u32>
@internal(intrinsic_load_uniform_vec3_f16) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<f16>
+fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<f16>
@internal(intrinsic_load_uniform_vec4_f32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<f32>
+fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<f32>
@internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<i32>
+fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<i32>
@internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<u32>
+fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<u32>
@internal(intrinsic_load_uniform_vec4_f16) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<f16>
+fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<f16>
-fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x2<f32> {
+fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x2<f32> {
return mat2x2<f32>(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)));
}
-fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x3<f32> {
+fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x3<f32> {
return mat2x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)));
}
-fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x4<f32> {
+fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x4<f32> {
return mat2x4<f32>(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)));
}
-fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat3x2<f32> {
+fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x2<f32> {
return mat3x2<f32>(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<uniform, UB, read>, offset : u32) -> mat3x3<f32> {
+fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x3<f32> {
return mat3x3<f32>(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<uniform, UB, read>, offset : u32) -> mat3x4<f32> {
+fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x4<f32> {
return mat3x4<f32>(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<uniform, UB, read>, offset : u32) -> mat4x2<f32> {
+fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x2<f32> {
return mat4x2<f32>(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<uniform, UB, read>, offset : u32) -> mat4x3<f32> {
+fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x3<f32> {
return mat4x3<f32>(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<uniform, UB, read>, offset : u32) -> mat4x4<f32> {
+fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x4<f32> {
return mat4x4<f32>(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<uniform, UB, read>, offset : u32) -> mat2x2<f16> {
+fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x2<f16> {
return mat2x2<f16>(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)));
}
-fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x3<f16> {
+fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x3<f16> {
return mat2x3<f16>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)));
}
-fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x4<f16> {
+fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x4<f16> {
return mat2x4<f16>(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)));
}
-fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat3x2<f16> {
+fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x2<f16> {
return mat3x2<f16>(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<uniform, UB, read>, offset : u32) -> mat3x3<f16> {
+fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x3<f16> {
return mat3x3<f16>(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<uniform, UB, read>, offset : u32) -> mat3x4<f16> {
+fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x4<f16> {
return mat3x4<f16>(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<uniform, UB, read>, offset : u32) -> mat4x2<f16> {
+fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x2<f16> {
return mat4x2<f16>(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<uniform, UB, read>, offset : u32) -> mat4x3<f16> {
+fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x3<f16> {
return mat4x3<f16>(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<uniform, UB, read>, offset : u32) -> mat4x4<f16> {
+fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x4<f16> {
return mat4x4<f16>(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<uniform, UB, read>, offset : u32) -> array<vec3<f32>, 2u> {
+fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> array<vec3<f32>, 2u> {
var arr : array<vec3<f32>, 2u>;
for(var i = 0u; (i < 2u); i = (i + 1u)) {
arr[i] = tint_symbol_8(buffer, (offset + (i * 16u)));
@@ -931,7 +931,7 @@
return arr;
}
-fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> array<mat4x2<f16>, 2u> {
+fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> array<mat4x2<f16>, 2u> {
var arr_1 : array<mat4x2<f16>, 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 @@
enable f16;
@internal(intrinsic_load_uniform_f32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> f32
+fn tint_symbol(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> i32
+fn tint_symbol_1(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> u32
+fn tint_symbol_2(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> f16
+fn tint_symbol_3(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, 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<uniform, UB, read>, offset : u32) -> vec2<f32>
+fn tint_symbol_4(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<f32>
@internal(intrinsic_load_uniform_vec2_i32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec2<i32>
+fn tint_symbol_5(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<i32>
@internal(intrinsic_load_uniform_vec2_u32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec2<u32>
+fn tint_symbol_6(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<u32>
@internal(intrinsic_load_uniform_vec2_f16) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec2<f16>
+fn tint_symbol_7(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec2<f16>
@internal(intrinsic_load_uniform_vec3_f32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<f32>
+fn tint_symbol_8(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<f32>
@internal(intrinsic_load_uniform_vec3_i32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<i32>
+fn tint_symbol_9(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<i32>
@internal(intrinsic_load_uniform_vec3_u32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<u32>
+fn tint_symbol_10(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<u32>
@internal(intrinsic_load_uniform_vec3_f16) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec3<f16>
+fn tint_symbol_11(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec3<f16>
@internal(intrinsic_load_uniform_vec4_f32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<f32>
+fn tint_symbol_12(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<f32>
@internal(intrinsic_load_uniform_vec4_i32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<i32>
+fn tint_symbol_13(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<i32>
@internal(intrinsic_load_uniform_vec4_u32) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<u32>
+fn tint_symbol_14(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<u32>
@internal(intrinsic_load_uniform_vec4_f16) @internal(disable_validation__function_has_no_body)
-fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> vec4<f16>
+fn tint_symbol_15(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> vec4<f16>
-fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x2<f32> {
+fn tint_symbol_16(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x2<f32> {
return mat2x2<f32>(tint_symbol_4(buffer, (offset + 0u)), tint_symbol_4(buffer, (offset + 8u)));
}
-fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x3<f32> {
+fn tint_symbol_17(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x3<f32> {
return mat2x3<f32>(tint_symbol_8(buffer, (offset + 0u)), tint_symbol_8(buffer, (offset + 16u)));
}
-fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x4<f32> {
+fn tint_symbol_18(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x4<f32> {
return mat2x4<f32>(tint_symbol_12(buffer, (offset + 0u)), tint_symbol_12(buffer, (offset + 16u)));
}
-fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat3x2<f32> {
+fn tint_symbol_19(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x2<f32> {
return mat3x2<f32>(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<uniform, UB, read>, offset : u32) -> mat3x3<f32> {
+fn tint_symbol_20(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x3<f32> {
return mat3x3<f32>(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<uniform, UB, read>, offset : u32) -> mat3x4<f32> {
+fn tint_symbol_21(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x4<f32> {
return mat3x4<f32>(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<uniform, UB, read>, offset : u32) -> mat4x2<f32> {
+fn tint_symbol_22(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x2<f32> {
return mat4x2<f32>(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<uniform, UB, read>, offset : u32) -> mat4x3<f32> {
+fn tint_symbol_23(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x3<f32> {
return mat4x3<f32>(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<uniform, UB, read>, offset : u32) -> mat4x4<f32> {
+fn tint_symbol_24(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x4<f32> {
return mat4x4<f32>(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<uniform, UB, read>, offset : u32) -> mat2x2<f16> {
+fn tint_symbol_25(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x2<f16> {
return mat2x2<f16>(tint_symbol_7(buffer, (offset + 0u)), tint_symbol_7(buffer, (offset + 4u)));
}
-fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x3<f16> {
+fn tint_symbol_26(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x3<f16> {
return mat2x3<f16>(tint_symbol_11(buffer, (offset + 0u)), tint_symbol_11(buffer, (offset + 8u)));
}
-fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat2x4<f16> {
+fn tint_symbol_27(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat2x4<f16> {
return mat2x4<f16>(tint_symbol_15(buffer, (offset + 0u)), tint_symbol_15(buffer, (offset + 8u)));
}
-fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> mat3x2<f16> {
+fn tint_symbol_28(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x2<f16> {
return mat3x2<f16>(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<uniform, UB, read>, offset : u32) -> mat3x3<f16> {
+fn tint_symbol_29(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x3<f16> {
return mat3x3<f16>(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<uniform, UB, read>, offset : u32) -> mat3x4<f16> {
+fn tint_symbol_30(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat3x4<f16> {
return mat3x4<f16>(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<uniform, UB, read>, offset : u32) -> mat4x2<f16> {
+fn tint_symbol_31(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x2<f16> {
return mat4x2<f16>(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<uniform, UB, read>, offset : u32) -> mat4x3<f16> {
+fn tint_symbol_32(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x3<f16> {
return mat4x3<f16>(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<uniform, UB, read>, offset : u32) -> mat4x4<f16> {
+fn tint_symbol_33(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> mat4x4<f16> {
return mat4x4<f16>(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<uniform, UB, read>, offset : u32) -> array<vec3<f32>, 2u> {
+fn tint_symbol_34(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> array<vec3<f32>, 2u> {
var arr : array<vec3<f32>, 2u>;
for(var i = 0u; (i < 2u); i = (i + 1u)) {
arr[i] = tint_symbol_8(buffer, (offset + (i * 16u)));
@@ -1202,7 +1202,7 @@
return arr;
}
-fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB, read>, offset : u32) -> array<mat4x2<f16>, 2u> {
+fn tint_symbol_35(@internal(disable_validation__function_parameter) buffer : ptr<uniform, UB>, offset : u32) -> array<mat4x2<f16>, 2u> {
var arr_1 : array<mat4x2<f16>, 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 8a69bd3..9c9c42f 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 @@
}
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 @@
[[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 @@
}
}
- // 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) {