validation: disallow atomic type constructors
The type of a type constructor must be constructible, which forbids atomics. Add checks for non-constructible types when validating arrays and structures, and then error on any type that isn't explicitly matched in the outer function. Replaces the separate check for pointers, which is no longer necessary. This also removes the validation for "an expression must not evaluate to an atomic type". The only test that we had for this is no longer valid (since the type constructor it used is now rejected). There are no other ways of hitting this particular error, since other validation rules will always kick in first. Change-Id: I2172b57ee4e8ee3066aaf0cedc4a26aaca642376 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/61800 Kokoro: Kokoro <noreply+kokoro@google.com> Auto-Submit: James Price <jrprice@google.com> Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com> Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
This commit is contained in:
parent
8094553c8a
commit
cbbb420952
|
@ -327,14 +327,6 @@ TEST_F(ResolverAtomicValidationTest, Local) {
|
|||
"12:34 error: function variable must have a constructible type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverAtomicValidationTest, NoAtomicExpr) {
|
||||
WrapInFunction(Construct(Source{{12, 34}}, ty.atomic<u32>()));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: an expression must not evaluate to an atomic type");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
|
|
@ -2241,13 +2241,6 @@ bool Resolver::Expression(ast::Expression* expr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto* ty = TypeOf(expr);
|
||||
if (ty->Is<sem::Atomic>()) {
|
||||
AddError("an expression must not evaluate to an atomic type",
|
||||
expr->source());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2600,11 +2593,6 @@ bool Resolver::Constructor(ast::ConstructorExpression* expr) {
|
|||
// Now that the argument types have been determined, make sure that they
|
||||
// obey the constructor type rules laid out in
|
||||
// https://gpuweb.github.io/gpuweb/wgsl.html#type-constructor-expr.
|
||||
if (type->Is<sem::Pointer>()) {
|
||||
AddError("cannot cast to a pointer", expr->source());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
if (auto* vec_type = type->As<sem::Vector>()) {
|
||||
ok = ValidateVectorConstructor(type_ctor, vec_type, type_name);
|
||||
|
@ -2616,6 +2604,9 @@ bool Resolver::Constructor(ast::ConstructorExpression* expr) {
|
|||
ok = ValidateArrayConstructor(type_ctor, arr_type);
|
||||
} else if (auto* struct_type = type->As<sem::Struct>()) {
|
||||
ok = ValidateStructureConstructor(type_ctor, struct_type);
|
||||
} else {
|
||||
AddError("type is not constructible", type_ctor->source());
|
||||
return false;
|
||||
}
|
||||
if (!ok) {
|
||||
return false;
|
||||
|
@ -2641,6 +2632,11 @@ bool Resolver::Constructor(ast::ConstructorExpression* expr) {
|
|||
bool Resolver::ValidateStructureConstructor(
|
||||
const ast::TypeConstructorExpression* ctor,
|
||||
const sem::Struct* struct_type) {
|
||||
if (!struct_type->IsConstructible()) {
|
||||
AddError("struct constructor has non-constructible type", ctor->source());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctor->values().size() > 0) {
|
||||
if (ctor->values().size() != struct_type->Members().size()) {
|
||||
std::string fm = ctor->values().size() < struct_type->Members().size()
|
||||
|
@ -2689,6 +2685,10 @@ bool Resolver::ValidateArrayConstructor(
|
|||
if (array_type->IsRuntimeSized()) {
|
||||
AddError("cannot init a runtime-sized array", ctor->source());
|
||||
return false;
|
||||
} else if (!elem_type->IsConstructible()) {
|
||||
AddError("array constructor has non-constructible element type",
|
||||
ctor->type()->As<ast::Array>()->type()->source());
|
||||
return false;
|
||||
} else if (!values.empty() && (values.size() != array_type->Count())) {
|
||||
std::string fm = values.size() < array_type->Count() ? "few" : "many";
|
||||
AddError("array constructor has too " + fm + " elements: expected " +
|
||||
|
|
|
@ -2148,6 +2148,44 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Struct_Empty) {
|
|||
}
|
||||
} // namespace StructConstructor
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, NonConstructibleType_Atomic) {
|
||||
WrapInFunction(
|
||||
Call("ignore", Construct(Source{{12, 34}}, ty.atomic(ty.i32()))));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: type is not constructible");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
NonConstructibleType_AtomicArray) {
|
||||
WrapInFunction(Call(
|
||||
"ignore", Construct(ty.array(ty.atomic(Source{{12, 34}}, ty.i32()), 4))));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
"12:34 error: array constructor has non-constructible element type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest,
|
||||
NonConstructibleType_AtomicStructMember) {
|
||||
auto* str = Structure("S", {Member("a", ty.atomic(ty.i32()))});
|
||||
WrapInFunction(Call("ignore", Construct(Source{{12, 34}}, ty.Of(str))));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: struct constructor has non-constructible type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeConstructorValidationTest, NonConstructibleType_Sampler) {
|
||||
WrapInFunction(Call(
|
||||
"ignore",
|
||||
Construct(Source{{12, 34}}, ty.sampler(ast::SamplerKind::kSampler))));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: type is not constructible");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
|
|
@ -919,7 +919,7 @@ TEST_F(ResolverTest, Expr_Constructor_Cast_Pointer) {
|
|||
WrapInFunction(Decl(vf), Decl(ip));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: cannot cast to a pointer");
|
||||
EXPECT_EQ(r()->error(), "12:34 error: type is not constructible");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue