resolver: Validate storage class for var initializers
Bug: chromium:1243418 Change-Id: Ia0cec7d77767783b2a3b85400a03c805b51699d8 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/62942 Commit-Queue: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
e9fdd50443
commit
231648c6a9
|
@ -520,15 +520,16 @@ Resolver::VariableInfo* Resolver::Variable(ast::Variable* var,
|
|||
}
|
||||
|
||||
auto storage_class = var->declared_storage_class();
|
||||
if (storage_class == ast::StorageClass::kNone) {
|
||||
if (storage_type->UnwrapRef()->is_handle()) {
|
||||
if (storage_class == ast::StorageClass::kNone && !var->is_const()) {
|
||||
// No declared storage class. Infer from usage / type.
|
||||
if (kind == VariableKind::kLocal) {
|
||||
storage_class = ast::StorageClass::kFunction;
|
||||
} else if (storage_type->UnwrapRef()->is_handle()) {
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
|
||||
// If the store type is a texture type or a sampler type, then the
|
||||
// variable declaration must not have a storage class decoration. The
|
||||
// storage class will always be handle.
|
||||
storage_class = ast::StorageClass::kUniformConstant;
|
||||
} else if (kind == VariableKind::kLocal && !var->is_const()) {
|
||||
storage_class = ast::StorageClass::kFunction;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,8 +546,9 @@ Resolver::VariableInfo* Resolver::Variable(ast::Variable* var,
|
|||
builder_->create<sem::Reference>(storage_type, storage_class, access);
|
||||
}
|
||||
|
||||
if (rhs_type && !ValidateVariableConstructor(var, storage_type, type_name,
|
||||
rhs_type, rhs_type_name)) {
|
||||
if (rhs_type &&
|
||||
!ValidateVariableConstructor(var, storage_class, storage_type, type_name,
|
||||
rhs_type, rhs_type_name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -573,6 +575,7 @@ ast::Access Resolver::DefaultAccessForStorageClass(
|
|||
}
|
||||
|
||||
bool Resolver::ValidateVariableConstructor(const ast::Variable* var,
|
||||
ast::StorageClass storage_class,
|
||||
const sem::Type* storage_type,
|
||||
const std::string& type_name,
|
||||
const sem::Type* rhs_type,
|
||||
|
@ -587,6 +590,26 @@ bool Resolver::ValidateVariableConstructor(const ast::Variable* var,
|
|||
var->source());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!var->is_const()) {
|
||||
switch (storage_class) {
|
||||
case ast::StorageClass::kPrivate:
|
||||
case ast::StorageClass::kFunction:
|
||||
break; // Allowed an initializer
|
||||
default:
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#var-and-let
|
||||
// Optionally has an initializer expression, if the variable is in the
|
||||
// private or function storage classes.
|
||||
AddError("var of storage class '" +
|
||||
std::string(ast::str(storage_class)) +
|
||||
"' cannot have an initializer. var initializers are only "
|
||||
"supported for the storage classes "
|
||||
"'private' and 'function'",
|
||||
var->source());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ class Resolver {
|
|||
bool ValidateSwitch(const ast::SwitchStatement* s);
|
||||
bool ValidateVariable(const VariableInfo* info);
|
||||
bool ValidateVariableConstructor(const ast::Variable* var,
|
||||
ast::StorageClass storage_class,
|
||||
const sem::Type* storage_type,
|
||||
const std::string& type_name,
|
||||
const sem::Type* rhs_type,
|
||||
|
|
|
@ -341,6 +341,18 @@ TEST_F(ResolverVarLetValidationTest, NonConstructibleType_InferredType) {
|
|||
"12:34 error: function variable must have a constructible type");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVarLetValidationTest, InvalidStorageClassForInitializer) {
|
||||
// var<workgroup> v : f32 = 1.23;
|
||||
Global(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kWorkgroup,
|
||||
Expr(1.23f));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: var of storage class 'workgroup' cannot have "
|
||||
"an initializer. var initializers are only supported for the "
|
||||
"storage classes 'private' and 'function'");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
|
Loading…
Reference in New Issue