[validation] Validates return statement
This CL checks if functions end with a return statement (v-0002) reworks previously added tests to pass enables related tests Bug: tint: 6 Change-Id: Iafe46581ccc50e146b33d33f9577d995a7f80d77 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/26722 Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com> Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
a532ac55d9
commit
d73f812c84
|
@ -52,9 +52,6 @@ class VertexPullingTransformHelper {
|
|||
tint::TypeDeterminer td(&ctx_, mod_.get());
|
||||
EXPECT_TRUE(td.Determine());
|
||||
|
||||
tint::Validator v;
|
||||
EXPECT_TRUE(v.Validate(mod_.get()));
|
||||
|
||||
transform_->SetVertexState(
|
||||
std::make_unique<VertexStateDescriptor>(std::move(vertex_state)));
|
||||
transform_->SetEntryPoint("main");
|
||||
|
|
|
@ -47,7 +47,7 @@ class TypeDeterminerHelper {
|
|||
class ValidateFunctionTest : public TypeDeterminerHelper,
|
||||
public testing::Test {};
|
||||
|
||||
TEST_F(ValidateFunctionTest, DISABLED_FunctionEndWithoutReturnStatement_Fail) {
|
||||
TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatement_Fail) {
|
||||
// fn func -> void { var a:i32 = 2; }
|
||||
|
||||
ast::type::I32Type i32;
|
||||
|
@ -69,11 +69,10 @@ TEST_F(ValidateFunctionTest, DISABLED_FunctionEndWithoutReturnStatement_Fail) {
|
|||
tint::ValidatorImpl v;
|
||||
EXPECT_FALSE(v.Validate(mod()));
|
||||
EXPECT_EQ(v.error(),
|
||||
"12:34: v-0002: 'function must end with a return statement 'func'");
|
||||
"12:34: v-0002: function must end with a return statement");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest,
|
||||
DISABLED_FunctionEndWithoutReturnStatementEmptyBody_Fail) {
|
||||
TEST_F(ValidateFunctionTest, FunctionEndWithoutReturnStatementEmptyBody_Fail) {
|
||||
// fn func -> void {}
|
||||
ast::type::VoidType void_type;
|
||||
ast::VariableList params;
|
||||
|
@ -85,7 +84,7 @@ TEST_F(ValidateFunctionTest,
|
|||
tint::ValidatorImpl v;
|
||||
EXPECT_FALSE(v.Validate(mod()));
|
||||
EXPECT_EQ(v.error(),
|
||||
"12:34: v-0002: 'function must end with a return statement 'func'");
|
||||
"12:34: v-0002: function must end with a return statement");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#include "src/validator_impl.h"
|
||||
#include "src/ast/function.h"
|
||||
#include "src/ast/variable_decl_statement.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -65,8 +66,13 @@ bool ValidatorImpl::ValidateFunction(const ast::Function* func) {
|
|||
if (!ValidateStatements(func->body())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
variable_stack_.pop_scope();
|
||||
|
||||
if (!func->get_last_statement() || !func->get_last_statement()->IsReturn()) {
|
||||
set_error(func->source(),
|
||||
"v-0002: function must end with a return statement");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,6 +316,7 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
|||
// var global_var: f32 = 2.1;
|
||||
// fn my_func() -> f32 {
|
||||
// global_var = 3.14;
|
||||
// return 3.14;
|
||||
// }
|
||||
ast::type::F32Type f32;
|
||||
auto global_var = std::make_unique<ast::Variable>(
|
||||
|
@ -330,6 +331,8 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
|||
auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
|
||||
std::make_unique<ast::FloatLiteral>(&f32, 3.14f));
|
||||
auto* rhs_ptr = rhs.get();
|
||||
auto return_expr = std::make_unique<ast::ScalarConstructorExpression>(
|
||||
std::make_unique<ast::FloatLiteral>(&f32, 3.14f));
|
||||
|
||||
ast::VariableList params;
|
||||
auto func =
|
||||
|
@ -338,6 +341,7 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
|||
auto body = std::make_unique<ast::BlockStatement>();
|
||||
body->append(std::make_unique<ast::AssignmentStatement>(
|
||||
Source{12, 34}, std::move(lhs), std::move(rhs)));
|
||||
body->append(std::make_unique<ast::ReturnStatement>(std::move(return_expr)));
|
||||
func->set_body(std::move(body));
|
||||
auto* func_ptr = func.get();
|
||||
mod()->AddFunction(std::move(func));
|
||||
|
@ -645,25 +649,27 @@ TEST_F(ValidatorTest, DISABLED_RedeclaredIdentifierInnerScope_False) {
|
|||
}
|
||||
|
||||
TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
|
||||
// func0 { var a : f32 = 2.0; }
|
||||
// func1 { var a : f32 = 3.0; }
|
||||
// func0 { var a : f32 = 2.0; return; }
|
||||
// func1 { var a : f32 = 3.0; return; }
|
||||
ast::type::F32Type f32;
|
||||
ast::type::VoidType void_type;
|
||||
auto var0 =
|
||||
std::make_unique<ast::Variable>("a", ast::StorageClass::kNone, &f32);
|
||||
var0->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
|
||||
std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
|
||||
|
||||
auto var1 =
|
||||
std::make_unique<ast::Variable>("a", ast::StorageClass::kNone, &f32);
|
||||
auto var1 = std::make_unique<ast::Variable>("a", ast::StorageClass::kNone,
|
||||
&void_type);
|
||||
var1->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
|
||||
std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
|
||||
|
||||
ast::VariableList params0;
|
||||
auto func0 =
|
||||
std::make_unique<ast::Function>("func0", std::move(params0), &f32);
|
||||
std::make_unique<ast::Function>("func0", std::move(params0), &void_type);
|
||||
auto body0 = std::make_unique<ast::BlockStatement>();
|
||||
body0->append(std::make_unique<ast::VariableDeclStatement>(Source{12, 34},
|
||||
std::move(var0)));
|
||||
body0->append(std::make_unique<ast::ReturnStatement>());
|
||||
func0->set_body(std::move(body0));
|
||||
|
||||
ast::VariableList params1;
|
||||
|
@ -672,6 +678,7 @@ TEST_F(ValidatorTest, RedeclaredIdentifierDifferentFunctions_Pass) {
|
|||
auto body1 = std::make_unique<ast::BlockStatement>();
|
||||
body1->append(std::make_unique<ast::VariableDeclStatement>(Source{13, 34},
|
||||
std::move(var1)));
|
||||
body1->append(std::make_unique<ast::ReturnStatement>());
|
||||
func1->set_body(std::move(body1));
|
||||
|
||||
mod()->AddFunction(std::move(func0));
|
||||
|
|
Loading…
Reference in New Issue