validation: disallow non-constructible assignments
The storage type of an assignment has to be constructible, which prevents stores to atomic or runtime-sized array types. Change-Id: Ie7bb703bb4c6953a4ddf0286f39d0d3e17b5b1d2 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/61801 Kokoro: Kokoro <noreply+kokoro@google.com> Auto-Submit: James Price <jrprice@google.com> Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
This commit is contained in:
parent
cbbb420952
commit
06c86a551e
|
@ -177,7 +177,7 @@ TEST_F(ResolverAssignmentValidationTest, AssignToConstant_Fail) {
|
||||||
"12:34 error: cannot assign to const\nnote: 'a' is declared here:");
|
"12:34 error: cannot assign to const\nnote: 'a' is declared here:");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverAssignmentValidationTest, AssignNonStorable_Fail) {
|
TEST_F(ResolverAssignmentValidationTest, AssignNonConstructible_Handle) {
|
||||||
// var a : texture_storage_1d<rgba8unorm, read>;
|
// var a : texture_storage_1d<rgba8unorm, read>;
|
||||||
// var b : texture_storage_1d<rgba8unorm, read>;
|
// var b : texture_storage_1d<rgba8unorm, read>;
|
||||||
// a = b;
|
// a = b;
|
||||||
|
@ -203,8 +203,51 @@ TEST_F(ResolverAssignmentValidationTest, AssignNonStorable_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"56:78 error: cannot store into a read-only type "
|
"56:78 error: storage type of assignment must be constructible");
|
||||||
"'texture_storage_1d<rgba8unorm, read>'");
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAssignmentValidationTest, AssignNonConstructible_Atomic) {
|
||||||
|
// [[block]] struct S { a : atomic<i32>; };
|
||||||
|
// [[group(0), binding(0)]] var<storage, read_write> v : S;
|
||||||
|
// v.a = v.a;
|
||||||
|
|
||||||
|
auto* s = Structure("S", {Member("a", ty.atomic(ty.i32()))},
|
||||||
|
{create<ast::StructBlockDecoration>()});
|
||||||
|
Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage,
|
||||||
|
ast::Access::kReadWrite,
|
||||||
|
ast::DecorationList{
|
||||||
|
create<ast::BindingDecoration>(0),
|
||||||
|
create<ast::GroupDecoration>(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"),
|
||||||
|
MemberAccessor("v", "a")));
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
"56:78 error: storage type of assignment must be constructible");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAssignmentValidationTest, AssignNonConstructible_RuntimeArray) {
|
||||||
|
// [[block]] struct S { a : array<f32>; };
|
||||||
|
// [[group(0), binding(0)]] var<storage, read_write> v : S;
|
||||||
|
// v.a = v.a;
|
||||||
|
|
||||||
|
auto* s = Structure("S", {Member("a", ty.array(ty.f32()))},
|
||||||
|
{create<ast::StructBlockDecoration>()});
|
||||||
|
Global(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage,
|
||||||
|
ast::Access::kReadWrite,
|
||||||
|
ast::DecorationList{
|
||||||
|
create<ast::BindingDecoration>(0),
|
||||||
|
create<ast::GroupDecoration>(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"),
|
||||||
|
MemberAccessor("v", "a")));
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
"56:78 error: storage type of assignment must be constructible");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -4330,6 +4330,10 @@ bool Resolver::ValidateAssignment(const ast::AssignmentStatement* a) {
|
||||||
a->source());
|
a->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!storage_type->IsConstructible()) {
|
||||||
|
AddError("storage type of assignment must be constructible", a->source());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (lhs_ref->Access() == ast::Access::kRead) {
|
if (lhs_ref->Access() == ast::Access::kRead) {
|
||||||
AddError(
|
AddError(
|
||||||
"cannot store into a read-only type '" + TypeNameOf(a->lhs()) + "'",
|
"cannot store into a read-only type '" + TypeNameOf(a->lhs()) + "'",
|
||||||
|
|
Loading…
Reference in New Issue