[validation] validates if global variables have a storage class
This CL moves the global variables checks to a function
Adds tests and checks for validation rule v-0022:
Global variables must have a storage class.
Bug: tint: 6
Change-Id: I2f2cd7df6e849bfd1ddfbca35568c6fc3345efa6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/27283
Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/validator_impl.cc b/src/validator_impl.cc
index 48fd7d2..968b2c6 100644
--- a/src/validator_impl.cc
+++ b/src/validator_impl.cc
@@ -35,13 +35,8 @@
return false;
}
function_stack_.push_scope();
- for (const auto& var : module->global_variables()) {
- if (variable_stack_.has(var->name())) {
- set_error(var->source(),
- "v-0011: redeclared global identifier '" + var->name() + "'");
- return false;
- }
- variable_stack_.set_global(var->name(), var.get());
+ if (!ValidateGlobalVariables(module->global_variables())) {
+ return false;
}
if (!CheckImports(module)) {
return false;
@@ -59,6 +54,24 @@
return true;
}
+bool ValidatorImpl::ValidateGlobalVariables(
+ const ast::VariableList& global_vars) {
+ for (const auto& var : global_vars) {
+ if (variable_stack_.has(var->name())) {
+ set_error(var->source(),
+ "v-0011: redeclared global identifier '" + var->name() + "'");
+ return false;
+ }
+ if (var->storage_class() == ast::StorageClass::kNone) {
+ set_error(var->source(),
+ "v-0022: global variables must have a storage class");
+ return false;
+ }
+ variable_stack_.set_global(var->name(), var.get());
+ }
+ return true;
+}
+
bool ValidatorImpl::ValidateEntryPoints(const ast::EntryPointList& eps) {
for (const auto& ep : eps) {
auto* ep_ptr = ep.get();
diff --git a/src/validator_impl.h b/src/validator_impl.h
index 3e38060..5f085fd 100644
--- a/src/validator_impl.h
+++ b/src/validator_impl.h
@@ -53,6 +53,10 @@
/// @param src the source causing the error
/// @param msg the error message
void set_error(const Source& src, const std::string& msg);
+ /// Validate global variables
+ /// @param global_vars list of global variables to check
+ /// @returns true if the validation was successful
+ bool ValidateGlobalVariables(const ast::VariableList& global_vars);
/// Validates Functions
/// @param funcs the functions to check
/// @returns true if the validation was successful
diff --git a/src/validator_test.cc b/src/validator_test.cc
index 3207ae7..6dc58c26 100644
--- a/src/validator_test.cc
+++ b/src/validator_test.cc
@@ -257,6 +257,30 @@
"12:34: v-000x: invalid assignment of '__i32' to '__f32'");
}
+TEST_F(ValidatorTest, GlobalVariableWithStorageClass_Pass) {
+ // var<in> gloabl_var: f32;
+ ast::type::F32Type f32;
+ auto global_var = std::make_unique<ast::Variable>(
+ Source{12, 34}, "global_var", ast::StorageClass::kInput, &f32);
+ mod()->AddGlobalVariable(std::move(global_var));
+ EXPECT_TRUE(td()->Determine()) << td()->error();
+ tint::ValidatorImpl v;
+ EXPECT_TRUE(v.Validate(mod())) << v.error();
+}
+
+TEST_F(ValidatorTest, GlobalVariableNoStorageClass_Fail) {
+ // var gloabl_var: f32;
+ ast::type::F32Type f32;
+ auto global_var = std::make_unique<ast::Variable>(
+ Source{12, 34}, "global_var", ast::StorageClass::kNone, &f32);
+ mod()->AddGlobalVariable(std::move(global_var));
+ EXPECT_TRUE(td()->Determine()) << td()->error();
+ tint::ValidatorImpl v;
+ EXPECT_FALSE(v.Validate(mod()));
+ EXPECT_EQ(v.error(),
+ "12:34: v-0022: global variables must have a storage class");
+}
+
TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Fail) {
// var global_var: f32 = 2.1;
// fn my_func() -> f32 {