Resolver: Validate resource binding decorations
Validate that:
* That resource variables have resource bindings
* Only resource variables have resource bindings
* That a [[binding]] decoration is paired with a [[group]]
* That binding points are not reused in the same entry point
Fixed: tint:235
Fixed: tint:645
Bug: tint:645
Change-Id: I2542934b4c6a2b4bbde48242932c04c796033a90
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50500
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/resolver/storage_class_validation_test.cc b/src/resolver/storage_class_validation_test.cc
index 9c36597..0db6410 100644
--- a/src/resolver/storage_class_validation_test.cc
+++ b/src/resolver/storage_class_validation_test.cc
@@ -36,8 +36,12 @@
}
TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
- // var<storage> g : bool;
- Global(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kStorage);
+ // var<storage> g : i32;
+ Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -49,7 +53,11 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
// var<storage> g : ptr<i32, input>;
Global(Source{{56, 78}}, "g", ty.pointer<i32>(ast::StorageClass::kInput),
- ast::StorageClass::kStorage);
+ ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -63,7 +71,11 @@
auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.array(s, 3);
auto ac = ty.access(ast::AccessControl::kReadOnly, a);
- Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kStorage);
+ Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -77,7 +89,11 @@
// var<storage> g : [[access(read)]] a;
auto* a = ty.alias("a", ty.bool_());
AST().AddConstructedType(a);
- Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
+ Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -89,7 +105,11 @@
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) {
// var<storage> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
- Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage);
+ Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -103,7 +123,11 @@
// var<storage> g : [[access(read)]] S;
auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())});
auto a = ty.access(ast::AccessControl::kReadOnly, s);
- Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
+ Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -119,7 +143,11 @@
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()});
auto a = ty.access(ast::AccessControl::kReadOnly, s);
- Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
+ Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_TRUE(r()->Resolve());
}
@@ -136,7 +164,11 @@
auto ac = ty.access(ast::AccessControl::kReadOnly, a1);
auto* a2 = ty.alias("a2", ac);
AST().AddConstructedType(a2);
- Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage);
+ Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_TRUE(r()->Resolve());
}
@@ -145,7 +177,12 @@
TEST_F(ResolverStorageClassValidationTest, UniformBufferBool) {
// var<uniform> g : bool;
- Global(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kUniform);
+ Global(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kUniform,
+ nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -157,7 +194,11 @@
TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
// var<uniform> g : ptr<i32, input>;
Global(Source{{56, 78}}, "g", ty.pointer<i32>(ast::StorageClass::kInput),
- ast::StorageClass::kUniform);
+ ast::StorageClass::kUniform, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -171,7 +212,11 @@
auto* s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.array(s, 3);
auto ac = ty.access(ast::AccessControl::kReadOnly, a);
- Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kUniform);
+ Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kUniform, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -185,7 +230,11 @@
// var<uniform> g : [[access(read)]] a;
auto* a = ty.alias("a", ty.bool_());
AST().AddConstructedType(a);
- Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform);
+ Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -198,7 +247,11 @@
// struct S { x : i32 };
// var<uniform> g : S;
auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())});
- Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform);
+ Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_FALSE(r()->Resolve());
@@ -213,7 +266,11 @@
// var<uniform> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()});
- Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform);
+ Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_TRUE(r()->Resolve());
}
@@ -226,7 +283,11 @@
{create<ast::StructBlockDecoration>()});
auto* a1 = ty.alias("a1", s);
AST().AddConstructedType(a1);
- Global(Source{{56, 78}}, "g", a1, ast::StorageClass::kUniform);
+ Global(Source{{56, 78}}, "g", a1, ast::StorageClass::kUniform, nullptr,
+ {
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
ASSERT_TRUE(r()->Resolve());
}