[validation] Update entry points validation v-0020

Remove irrelevant unit tests
Add/Update ValdiateEntryPoints function
Update known failure file

Bug: tint:296
Change-Id: I7d5c9c96fcca29f3e0a4c0315eb8ce869160a3ea
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32220
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: David Neto <dneto@google.com>
This commit is contained in:
Sarah Mashayekhi 2020-11-11 14:21:05 +00:00 committed by Commit Bot service account
parent 1bbafa3445
commit 3b04058d19
4 changed files with 51 additions and 86 deletions

View File

@ -316,65 +316,27 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
"'vtx_func'");
}
TEST_F(ValidateFunctionTest, PipelineStageNamePair_MustBeUnique_Fail) {
// [[stage(vertex)]]
// fn main() -> void { return ;}
// [[stage(vertex)]]
// fn main() -> void { return; }
ast::type::VoidType void_type;
ast::VariableList params;
auto func = std::make_unique<ast::Function>(
Source{Source::Location{5, 6}}, "main", std::move(params), &void_type);
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::ReturnStatement>());
func->set_body(std::move(body));
func->add_decoration(std::make_unique<ast::StageDecoration>(
ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(func));
func = std::make_unique<ast::Function>(Source{Source::Location{12, 34}},
"main", std::move(params), &void_type);
body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::ReturnStatement>());
func->set_body(std::move(body));
func->add_decoration(std::make_unique<ast::StageDecoration>(
ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(func));
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_FALSE(v()->Validate(mod()));
EXPECT_EQ(v()->error(),
"12:34: v-0020: The pair of <entry point name, pipeline stage> "
"must be unique");
}
TEST_F(ValidateFunctionTest, PipelineStageNamePair_MustBeUnique_Pass) {
// [[stage(vertex)]]
// fn main() -> void { return; }
TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) {
// [[stage(fragment)]]
// [[stage(vertex)]]
// fn main() -> void { return; }
ast::type::VoidType void_type;
ast::VariableList params;
auto func = std::make_unique<ast::Function>(
Source{Source::Location{5, 6}}, "main", std::move(params), &void_type);
Source{Source::Location{12, 34}}, "main", std::move(params), &void_type);
auto body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::ReturnStatement>());
func->set_body(std::move(body));
func->add_decoration(std::make_unique<ast::StageDecoration>(
ast::PipelineStage::kVertex, Source{}));
mod()->AddFunction(std::move(func));
func = std::make_unique<ast::Function>(Source{Source::Location{12, 34}},
"main", std::move(params), &void_type);
body = std::make_unique<ast::BlockStatement>();
body->append(std::make_unique<ast::ReturnStatement>());
func->set_body(std::move(body));
func->add_decoration(std::make_unique<ast::StageDecoration>(
ast::PipelineStage::kFragment, Source{}));
mod()->AddFunction(std::move(func));
EXPECT_TRUE(td()->Determine()) << td()->error();
EXPECT_TRUE(v()->Validate(mod())) << v()->error();
EXPECT_FALSE(v()->Validate(mod()));
EXPECT_EQ(
v()->error(),
"12:34: v-0020: only one stage decoration permitted per entry point");
}
TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) {

View File

@ -51,7 +51,9 @@ bool ValidatorImpl::Validate(const ast::Module* module) {
if (!ValidateFunctions(module->functions())) {
return false;
}
if (!ValidateEntryPoint(module->functions())) {
return false;
}
function_stack_.pop_scope();
return true;
@ -82,49 +84,13 @@ bool ValidatorImpl::ValidateGlobalVariables(
}
bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
ScopeStack<ast::PipelineStage> entry_point_map;
entry_point_map.push_scope();
size_t pipeline_count = 0;
for (const auto& func : funcs) {
// The entry points will be checked later to see if their duplicated
if (function_stack_.has(func->name()) &&
!entry_point_map.has(func->name())) {
if (function_stack_.has(func->name())) {
set_error(func->source(),
"v-0016: function names must be unique '" + func->name() + "'");
return false;
}
if (func->IsEntryPoint()) {
pipeline_count++;
if (!func->return_type()->IsVoid()) {
set_error(func->source(),
"v-0024: Entry point function must return void: '" +
func->name() + "'");
return false;
}
if (func->params().size() != 0) {
set_error(func->source(),
"v-0023: Entry point function must accept no parameters: '" +
func->name() + "'");
return false;
}
ast::PipelineStage pipeline_stage;
if (entry_point_map.get(func->name(), &pipeline_stage)) {
if (pipeline_stage == func->pipeline_stage()) {
set_error(
func->source(),
"v-0020: The pair of <entry point name, pipeline stage> must "
"be unique");
return false;
}
}
entry_point_map.set(func->name(), func->pipeline_stage());
}
function_stack_.set(func->name(), func.get());
current_function_ = func.get();
if (!ValidateFunction(func.get())) {
@ -133,13 +99,47 @@ bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
current_function_ = nullptr;
}
if (pipeline_count == 0) {
return true;
}
bool ValidatorImpl::ValidateEntryPoint(const ast::FunctionList& funcs) {
auto shader_is_present = false;
for (const auto& func : funcs) {
if (func->IsEntryPoint()) {
shader_is_present = true;
if (!func->params().empty()) {
set_error(func->source(),
"v-0023: Entry point function must accept no parameters: '" +
func->name() + "'");
return false;
}
if (!func->return_type()->IsVoid()) {
set_error(func->source(),
"v-0024: Entry point function must return void: '" +
func->name() + "'");
return false;
}
auto stage_deco_count = 0;
for (const auto& deco : func->decorations()) {
if (deco->IsStage()) {
stage_deco_count++;
}
}
if (stage_deco_count > 1) {
set_error(
func->source(),
"v-0020: only one stage decoration permitted per entry point");
return false;
}
}
}
if (!shader_is_present) {
set_error(Source{},
"v-0003: At least one of vertex, fragment or compute shader must "
"be present");
return false;
}
return true;
}

View File

@ -113,6 +113,10 @@ class ValidatorImpl {
/// @param c the case statement to check
/// @returns true if the valdiation was successful
bool ValidateCase(const ast::CaseStatement* c);
/// Validates entry points
/// @param funcs the functions to check
/// @returns true if the valdiation was successful
bool ValidateEntryPoint(const ast::FunctionList& funcs);
private:
std::string error_;

View File

@ -1,6 +1,5 @@
break-outside-for-or-switch.fail.wgsl
continue-outside-for.fail.wgsl
duplicate-entry-point.fail.wgsl
duplicate-stuct-name-v2.fail.wgsl
duplicate-stuct-name.fail.wgsl
duplicate-var-name-within-func.fail.wgsl