Finish moving call validation from Validator to Resolver

Call validation was already implemented in Resolver. This change
completes it by deleting the relevant code in Validator, and moving and
updating the builtins validation test to use the Resolver.

Also added the "v-0004" error code for when detecting recursion, as was
done for the similar error in the Validator.

Bug: tint:642
Bug: tint:487

Change-Id: If7973bfd2d19681a0cbf48c6d427e17a3b927cde
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45463
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Antonio Maiorano 2021-03-22 17:42:06 +00:00 committed by Commit Bot service account
parent 4682e3fc31
commit 06feb3f287
7 changed files with 124 additions and 330 deletions

View File

@ -466,6 +466,7 @@ if(${TINT_BUILD_TESTS})
intrinsic_table_test.cc intrinsic_table_test.cc
program_test.cc program_test.cc
resolver/assignment_validation_test.cc resolver/assignment_validation_test.cc
resolver/builtins_validation_test.cc
resolver/decoration_validation_test.cc resolver/decoration_validation_test.cc
resolver/function_validation_test.cc resolver/function_validation_test.cc
resolver/host_shareable_validation_test.cc resolver/host_shareable_validation_test.cc
@ -509,7 +510,6 @@ if(${TINT_BUILD_TESTS})
utils/tmpfile_test.cc utils/tmpfile_test.cc
utils/tmpfile.h utils/tmpfile.h
utils/unique_vector_test.cc utils/unique_vector_test.cc
validator/validator_builtins_test.cc
validator/validator_control_block_test.cc validator/validator_control_block_test.cc
validator/validator_decoration_test.cc validator/validator_decoration_test.cc
validator/validator_function_test.cc validator/validator_function_test.cc

View File

@ -12,111 +12,91 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/validator/validator_test_helper.h" #include "src/resolver/resolver_test_helper.h"
namespace tint { namespace tint {
namespace {
class ResolverBuiltinsValidationTest : public resolver::TestHelper,
public testing::Test {};
class ValidatorBuiltinsTest : public ValidatorTestHelper, TEST_F(ResolverBuiltinsValidationTest, Length_Float_Scalar) {
public testing::Test {};
TEST_F(ValidatorBuiltinsTest, Length_Float_Scalar) {
auto* builtin = Call("length", 1.0f); auto* builtin = Call("length", 1.0f);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Length_Float_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec2) {
auto* builtin = Call("length", vec2<float>(1.0f, 1.0f)); auto* builtin = Call("length", vec2<float>(1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Length_Float_Vec3) { TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec3) {
auto* builtin = Call("length", vec3<float>(1.0f, 1.0f, 1.0f)); auto* builtin = Call("length", vec3<float>(1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Length_Float_Vec4) { TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec4) {
auto* builtin = Call("length", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f)); auto* builtin = Call("length", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Distance_Float_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Scalar) {
auto* builtin = Call("distance", 1.0f, 1.0f); auto* builtin = Call("distance", 1.0f, 1.0f);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Distance_Float_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec2) {
auto* builtin = auto* builtin =
Call("distance", vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f)); Call("distance", vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Distance_Float_Vec3) { TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec3) {
auto* builtin = Call("distance", vec3<float>(1.0f, 1.0f, 1.0f), auto* builtin = Call("distance", vec3<float>(1.0f, 1.0f, 1.0f),
vec3<float>(1.0f, 1.0f, 1.0f)); vec3<float>(1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Distance_Float_Vec4) { TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec4) {
auto* builtin = Call("distance", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), auto* builtin = Call("distance", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f)); vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Determinant_Mat2x2) { TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat2x2) {
auto* builtin = Call("determinant", mat2x2<float>(vec2<float>(1.0f, 1.0f), auto* builtin = Call("determinant", mat2x2<float>(vec2<float>(1.0f, 1.0f),
vec2<float>(1.0f, 1.0f))); vec2<float>(1.0f, 1.0f)));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Determinant_Mat3x3) { TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat3x3) {
auto* builtin = auto* builtin =
Call("determinant", mat3x3<float>(vec3<float>(1.0f, 1.0f, 1.0f), Call("determinant", mat3x3<float>(vec3<float>(1.0f, 1.0f, 1.0f),
vec3<float>(1.0f, 1.0f, 1.0f), vec3<float>(1.0f, 1.0f, 1.0f),
vec3<float>(1.0f, 1.0f, 1.0f))); vec3<float>(1.0f, 1.0f, 1.0f)));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Determinant_Mat4x4) { TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat4x4) {
auto* builtin = auto* builtin =
Call("determinant", mat4x4<float>(vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Call("determinant", mat4x4<float>(vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
@ -124,251 +104,198 @@ TEST_F(ValidatorBuiltinsTest, Determinant_Mat4x4) {
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f))); vec4<float>(1.0f, 1.0f, 1.0f, 1.0f)));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Frexp_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Frexp_Scalar) {
auto* a = Var("a", ty.i32(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.i32(), ast::StorageClass::kFunction);
RegisterVariable(a);
auto* builtin = Call("frexp", 1.0f, Expr("a")); auto* builtin = Call("frexp", 1.0f, Expr("a"));
WrapInFunction(builtin); WrapInFunction(Decl(a), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>()); EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Frexp_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec2) {
auto* a = Var("a", ty.vec2<int>(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.vec2<int>(), ast::StorageClass::kFunction);
auto* b = Const("b", auto* b = Const("b",
create<type::Pointer>(create<type::Vector>(ty.i32(), 2), create<type::Pointer>(create<type::Vector>(ty.i32(), 2),
ast::StorageClass::kWorkgroup), ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("frexp", vec2<float>(1.0f, 1.0f), Expr("b")); auto* builtin = Call("frexp", vec2<float>(1.0f, 1.0f), Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Frexp_Vec3) { TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec3) {
auto* a = Var("a", ty.vec3<int>(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.vec3<int>(), ast::StorageClass::kFunction);
auto* b = Const("b", auto* b = Const("b",
create<type::Pointer>(create<type::Vector>(ty.i32(), 3), create<type::Pointer>(create<type::Vector>(ty.i32(), 3),
ast::StorageClass::kWorkgroup), ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("frexp", vec3<float>(1.0f, 1.0f, 1.0f), Expr("b")); auto* builtin = Call("frexp", vec3<float>(1.0f, 1.0f, 1.0f), Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Frexp_Vec4) { TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec4) {
auto* a = Var("a", ty.vec4<int>(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.vec4<int>(), ast::StorageClass::kFunction);
auto* b = Const("b", auto* b = Const("b",
create<type::Pointer>(create<type::Vector>(ty.i32(), 4), create<type::Pointer>(create<type::Vector>(ty.i32(), 4),
ast::StorageClass::kWorkgroup), ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("frexp", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b")); auto* builtin = Call("frexp", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Modf_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Modf_Scalar) {
auto* a = Var("a", ty.f32(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.f32(), ast::StorageClass::kFunction);
auto* b = Const("b", ty.pointer<float>(ast::StorageClass::kWorkgroup), auto* b = Const("b", ty.pointer<float>(ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("modf", 1.0f, Expr("b")); auto* builtin = Call("modf", 1.0f, Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>()); EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Modf_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Modf_Vec2) {
auto* a = Var("a", ty.vec2<float>(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.vec2<float>(), ast::StorageClass::kFunction);
auto* b = Const("b", auto* b = Const("b",
create<type::Pointer>(create<type::Vector>(ty.f32(), 2), create<type::Pointer>(create<type::Vector>(ty.f32(), 2),
ast::StorageClass::kWorkgroup), ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("modf", vec2<float>(1.0f, 1.0f), Expr("b")); auto* builtin = Call("modf", vec2<float>(1.0f, 1.0f), Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Modf_Vec3) { TEST_F(ResolverBuiltinsValidationTest, Modf_Vec3) {
auto* a = Var("a", ty.vec3<float>(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.vec3<float>(), ast::StorageClass::kFunction);
auto* b = Const("b", auto* b = Const("b",
create<type::Pointer>(create<type::Vector>(ty.f32(), 3), create<type::Pointer>(create<type::Vector>(ty.f32(), 3),
ast::StorageClass::kWorkgroup), ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("modf", vec3<float>(1.0f, 1.0f, 1.0f), Expr("b")); auto* builtin = Call("modf", vec3<float>(1.0f, 1.0f, 1.0f), Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Modf_Vec4) { TEST_F(ResolverBuiltinsValidationTest, Modf_Vec4) {
auto* a = Var("a", ty.vec4<float>(), ast::StorageClass::kWorkgroup); auto* a = Var("a", ty.vec4<float>(), ast::StorageClass::kFunction);
auto* b = Const("b", auto* b = Const("b",
create<type::Pointer>(create<type::Vector>(ty.f32(), 4), create<type::Pointer>(create<type::Vector>(ty.f32(), 4),
ast::StorageClass::kWorkgroup), ast::StorageClass::kFunction),
Expr("a"), {}); Expr("a"), {});
RegisterVariable(a);
RegisterVariable(b);
auto* builtin = Call("modf", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b")); auto* builtin = Call("modf", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b"));
WrapInFunction(builtin); WrapInFunction(Decl(a), Decl(b), builtin);
ValidatorImpl& v = Build();
EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is<type::Pointer>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Cross_Float_Vec3) { TEST_F(ResolverBuiltinsValidationTest, Cross_Float_Vec3) {
auto* builtin = Call("cross", vec3<float>(1.0f, 1.0f, 1.0f), auto* builtin = Call("cross", vec3<float>(1.0f, 1.0f, 1.0f),
vec3<float>(1.0f, 1.0f, 1.0f)); vec3<float>(1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Dot_Float_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec2) {
auto* builtin = Call("dot", vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f)); auto* builtin = Call("dot", vec2<float>(1.0f, 1.0f), vec2<float>(1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Dot_Float_Vec3) { TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec3) {
auto* builtin = auto* builtin =
Call("dot", vec3<float>(1.0f, 1.0f, 1.0f), vec3<float>(1.0f, 1.0f, 1.0f)); Call("dot", vec3<float>(1.0f, 1.0f, 1.0f), vec3<float>(1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Dot_Float_Vec4) { TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec4) {
auto* builtin = Call("dot", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f), auto* builtin = Call("dot", vec4<float>(1.0f, 1.0f, 1.0f, 1.0f),
vec4<float>(1.0f, 1.0f, 1.0f, 1.0f)); vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Select_Float_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Select_Float_Scalar) {
auto* builtin = Call("select", Expr(1.0f), Expr(1.0f), Expr(true)); auto* builtin = Call("select", Expr(1.0f), Expr(1.0f), Expr(true));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Select_Integer_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Scalar) {
auto* builtin = Call("select", Expr(1), Expr(1), Expr(true)); auto* builtin = Call("select", Expr(1), Expr(1), Expr(true));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Select_Boolean_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Select_Boolean_Scalar) {
auto* builtin = Call("select", Expr(true), Expr(true), Expr(true)); auto* builtin = Call("select", Expr(true), Expr(true), Expr(true));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Select_Float_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Select_Float_Vec2) {
auto* builtin = Call("select", vec2<float>(1.0f, 1.0f), auto* builtin = Call("select", vec2<float>(1.0f, 1.0f),
vec2<float>(1.0f, 1.0f), vec2<bool>(true, true)); vec2<float>(1.0f, 1.0f), vec2<bool>(true, true));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Select_Integer_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Vec2) {
auto* builtin = auto* builtin =
Call("select", vec2<int>(1, 1), vec2<int>(1, 1), vec2<bool>(true, true)); Call("select", vec2<int>(1, 1), vec2<int>(1, 1), vec2<bool>(true, true));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_F(ValidatorBuiltinsTest, Select_Boolean_Vec2) { TEST_F(ResolverBuiltinsValidationTest, Select_Boolean_Vec2) {
auto* builtin = Call("select", vec2<bool>(true, true), vec2<bool>(true, true), auto* builtin = Call("select", vec2<bool>(true, true), vec2<bool>(true, true),
vec2<bool>(true, true)); vec2<bool>(true, true));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
template <typename T> template <typename T>
class ValidatorBuiltinsTestWithParams : public ValidatorTestHelper, class ResolverBuiltinsValidationTestWithParams
public testing::TestWithParam<T> {}; : public resolver::TestHelper,
public testing::TestWithParam<T> {};
using FloatAllMatching = using FloatAllMatching =
ValidatorBuiltinsTestWithParams<std::tuple<std::string, uint32_t>>; ResolverBuiltinsValidationTestWithParams<std::tuple<std::string, uint32_t>>;
TEST_P(FloatAllMatching, Scalar) { TEST_P(FloatAllMatching, Scalar) {
std::string name = std::get<0>(GetParam()); std::string name = std::get<0>(GetParam());
@ -381,10 +308,8 @@ TEST_P(FloatAllMatching, Scalar) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>()); EXPECT_TRUE(TypeOf(builtin)->Is<type::F32>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(FloatAllMatching, Vec2) { TEST_P(FloatAllMatching, Vec2) {
@ -398,10 +323,8 @@ TEST_P(FloatAllMatching, Vec2) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(FloatAllMatching, Vec3) { TEST_P(FloatAllMatching, Vec3) {
@ -415,10 +338,8 @@ TEST_P(FloatAllMatching, Vec3) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(FloatAllMatching, Vec4) { TEST_P(FloatAllMatching, Vec4) {
@ -432,13 +353,11 @@ TEST_P(FloatAllMatching, Vec4) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin)->is_float_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
FloatAllMatching, FloatAllMatching,
::testing::Values(std::make_tuple("abs", 1), ::testing::Values(std::make_tuple("abs", 1),
std::make_tuple("acos", 1), std::make_tuple("acos", 1),
@ -484,7 +403,7 @@ INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest,
std::make_tuple("trunc", 1))); std::make_tuple("trunc", 1)));
using IntegerAllMatching = using IntegerAllMatching =
ValidatorBuiltinsTestWithParams<std::tuple<std::string, uint32_t>>; ResolverBuiltinsValidationTestWithParams<std::tuple<std::string, uint32_t>>;
TEST_P(IntegerAllMatching, ScalarUnsigned) { TEST_P(IntegerAllMatching, ScalarUnsigned) {
std::string name = std::get<0>(GetParam()); std::string name = std::get<0>(GetParam());
@ -497,10 +416,8 @@ TEST_P(IntegerAllMatching, ScalarUnsigned) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->Is<type::U32>()); EXPECT_TRUE(TypeOf(builtin)->Is<type::U32>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, Vec2Unsigned) { TEST_P(IntegerAllMatching, Vec2Unsigned) {
@ -514,10 +431,8 @@ TEST_P(IntegerAllMatching, Vec2Unsigned) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector()); EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, Vec3Unsigned) { TEST_P(IntegerAllMatching, Vec3Unsigned) {
@ -531,10 +446,8 @@ TEST_P(IntegerAllMatching, Vec3Unsigned) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector()); EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, Vec4Unsigned) { TEST_P(IntegerAllMatching, Vec4Unsigned) {
@ -548,10 +461,8 @@ TEST_P(IntegerAllMatching, Vec4Unsigned) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector()); EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, ScalarSigned) { TEST_P(IntegerAllMatching, ScalarSigned) {
@ -565,10 +476,8 @@ TEST_P(IntegerAllMatching, ScalarSigned) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->Is<type::I32>()); EXPECT_TRUE(TypeOf(builtin)->Is<type::I32>());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, Vec2Signed) { TEST_P(IntegerAllMatching, Vec2Signed) {
@ -582,10 +491,8 @@ TEST_P(IntegerAllMatching, Vec2Signed) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector()); EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, Vec3Signed) { TEST_P(IntegerAllMatching, Vec3Signed) {
@ -599,10 +506,8 @@ TEST_P(IntegerAllMatching, Vec3Signed) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector()); EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(IntegerAllMatching, Vec4Signed) { TEST_P(IntegerAllMatching, Vec4Signed) {
@ -616,13 +521,11 @@ TEST_P(IntegerAllMatching, Vec4Signed) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector()); EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector());
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
IntegerAllMatching, IntegerAllMatching,
::testing::Values(std::make_tuple("abs", 1), ::testing::Values(std::make_tuple("abs", 1),
std::make_tuple("clamp", 3), std::make_tuple("clamp", 3),
@ -632,7 +535,7 @@ INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest,
std::make_tuple("reverseBits", 1))); std::make_tuple("reverseBits", 1)));
using BooleanVectorInput = using BooleanVectorInput =
ValidatorBuiltinsTestWithParams<std::tuple<std::string, uint32_t>>; ResolverBuiltinsValidationTestWithParams<std::tuple<std::string, uint32_t>>;
TEST_P(BooleanVectorInput, Vec2) { TEST_P(BooleanVectorInput, Vec2) {
std::string name = std::get<0>(GetParam()); std::string name = std::get<0>(GetParam());
@ -645,9 +548,7 @@ TEST_P(BooleanVectorInput, Vec2) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(BooleanVectorInput, Vec3) { TEST_P(BooleanVectorInput, Vec3) {
@ -661,9 +562,7 @@ TEST_P(BooleanVectorInput, Vec3) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
TEST_P(BooleanVectorInput, Vec4) { TEST_P(BooleanVectorInput, Vec4) {
@ -677,44 +576,41 @@ TEST_P(BooleanVectorInput, Vec4) {
auto* builtin = Call(name, params); auto* builtin = Call(name, params);
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
BooleanVectorInput, BooleanVectorInput,
::testing::Values(std::make_tuple("all", 1), ::testing::Values(std::make_tuple("all", 1),
std::make_tuple("any", 1))); std::make_tuple("any", 1)));
using DataPacking4x8 = ValidatorBuiltinsTestWithParams<std::string>; using DataPacking4x8 = ResolverBuiltinsValidationTestWithParams<std::string>;
TEST_P(DataPacking4x8, Float_Vec4) { TEST_P(DataPacking4x8, Float_Vec4) {
auto name = GetParam(); auto name = GetParam();
auto* builtin = Call(name, vec4<float>(1.0f, 1.0f, 1.0f, 1.0f)); auto* builtin = Call(name, vec4<float>(1.0f, 1.0f, 1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
DataPacking4x8, DataPacking4x8,
::testing::Values("pack4x8snorm", "pack4x8unorm")); ::testing::Values("pack4x8snorm", "pack4x8unorm"));
using DataPacking2x16 = ValidatorBuiltinsTestWithParams<std::string>; using DataPacking2x16 = ResolverBuiltinsValidationTestWithParams<std::string>;
TEST_P(DataPacking2x16, Float_Vec2) { TEST_P(DataPacking2x16, Float_Vec2) {
auto name = GetParam(); auto name = GetParam();
auto* builtin = Call(name, vec2<float>(1.0f, 1.0f)); auto* builtin = Call(name, vec2<float>(1.0f, 1.0f));
WrapInFunction(builtin); WrapInFunction(builtin);
ValidatorImpl& v = Build(); EXPECT_TRUE(r()->Resolve()) << r()->error();
EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error();
} }
INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest,
DataPacking2x16, DataPacking2x16,
::testing::Values("pack2x16snorm", ::testing::Values("pack2x16snorm",
"pack2x16unorm", "pack2x16unorm",
"pack2x16float")); "pack2x16float"));
} // namespace
} // namespace tint } // namespace tint

View File

@ -582,7 +582,8 @@ bool Resolver::Call(ast::CallExpression* call) {
auto callee_func_it = symbol_to_function_.find(ident->symbol()); auto callee_func_it = symbol_to_function_.find(ident->symbol());
if (callee_func_it == symbol_to_function_.end()) { if (callee_func_it == symbol_to_function_.end()) {
if (current_function_->declaration->symbol() == ident->symbol()) { if (current_function_->declaration->symbol() == ident->symbol()) {
diagnostics_.add_error("recursion is not permitted. '" + name + diagnostics_.add_error("v-0004",
"recursion is not permitted. '" + name +
"' attempted to call itself.", "' attempted to call itself.",
call->source()); call->source());
} else { } else {
@ -637,39 +638,6 @@ bool Resolver::IntrinsicCall(ast::CallExpression* call,
if (!result.intrinsic) { if (!result.intrinsic) {
// Intrinsic lookup failed. // Intrinsic lookup failed.
diagnostics_.add(result.diagnostics); diagnostics_.add(result.diagnostics);
// TODO(bclayton): https://crbug.com/tint/487
// The Validator expects intrinsic signature mismatches to still produce
// type information. The rules for what the Validator expects are rather
// bespoke. Try to match what the Validator expects. As the Validator's
// checks on intrinsics is now almost entirely covered by the
// IntrinsicTable, we should remove the Validator checks on intrinsic
// signatures and remove these hacks.
semantic::ParameterList parameters;
parameters.reserve(arg_tys.size());
for (auto* arg : arg_tys) {
parameters.emplace_back(semantic::Parameter{arg});
}
type::Type* ret_ty = nullptr;
switch (intrinsic_type) {
case IntrinsicType::kCross:
ret_ty = builder_->ty.vec3<ProgramBuilder::f32>();
break;
case IntrinsicType::kDeterminant:
ret_ty = builder_->create<type::F32>();
break;
case IntrinsicType::kArrayLength:
ret_ty = builder_->create<type::U32>();
break;
default:
ret_ty = arg_tys.empty() ? builder_->ty.void_() : arg_tys[0];
break;
}
auto* intrinsic = builder_->create<semantic::Intrinsic>(intrinsic_type,
ret_ty, parameters);
builder_->Sem().Add(call, builder_->create<semantic::Call>(
call, intrinsic, current_statement_));
SetType(call, ret_ty);
return false; return false;
} }

View File

@ -127,7 +127,8 @@ TEST_F(ResolverValidationTest, Stmt_Call_recursive) {
EXPECT_FALSE(r()->Resolve()); EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), EXPECT_EQ(r()->error(),
"12:34 error: recursion is not permitted. 'main' attempted to call " "12:34 error v-0004: recursion is not permitted. 'main' attempted "
"to call "
"itself."); "itself.");
} }

View File

@ -257,12 +257,7 @@ bool ValidatorImpl::ValidateStatement(const ast::Statement* stmt) {
return false; return false;
} }
if (auto* v = stmt->As<ast::VariableDeclStatement>()) { if (auto* v = stmt->As<ast::VariableDeclStatement>()) {
bool constructor_valid = return ValidateDeclStatement(v);
v->variable()->has_constructor()
? ValidateExpression(v->variable()->constructor())
: true;
return constructor_valid && ValidateDeclStatement(v);
} }
if (auto* a = stmt->As<ast::AssignmentStatement>()) { if (auto* a = stmt->As<ast::AssignmentStatement>()) {
return ValidateAssign(a); return ValidateAssign(a);
@ -270,9 +265,6 @@ bool ValidatorImpl::ValidateStatement(const ast::Statement* stmt) {
if (auto* r = stmt->As<ast::ReturnStatement>()) { if (auto* r = stmt->As<ast::ReturnStatement>()) {
return ValidateReturnStatement(r); return ValidateReturnStatement(r);
} }
if (auto* c = stmt->As<ast::CallStatement>()) {
return ValidateCallExpr(c->expr());
}
if (auto* s = stmt->As<ast::SwitchStatement>()) { if (auto* s = stmt->As<ast::SwitchStatement>()) {
return ValidateSwitch(s); return ValidateSwitch(s);
} }
@ -286,10 +278,6 @@ bool ValidatorImpl::ValidateStatement(const ast::Statement* stmt) {
} }
bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) { bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) {
if (!ValidateExpression(s->condition())) {
return false;
}
auto* cond_type = program_->Sem().Get(s->condition())->Type()->UnwrapAll(); auto* cond_type = program_->Sem().Get(s->condition())->Type()->UnwrapAll();
if (!cond_type->is_integer_scalar()) { if (!cond_type->is_integer_scalar()) {
add_error(s->condition()->source(), "v-0025", add_error(s->condition()->source(), "v-0025",
@ -358,41 +346,6 @@ bool ValidatorImpl::ValidateCase(const ast::CaseStatement* c) {
return true; return true;
} }
bool ValidatorImpl::ValidateCallExpr(const ast::CallExpression* expr) {
if (!expr) {
// TODO(sarahM0): Here and other Validate.*: figure out whether return
// false or true
return false;
}
auto* call = program_->Sem().Get(expr);
if (call == nullptr) {
add_error(expr->source(), "CallExpression is missing semantic information");
return false;
}
auto* target = call->Target();
if (target->Is<semantic::Intrinsic>()) {
// TODO(bclayton): Add intrinsic validation checks here.
return true;
}
if (auto* func = target->As<semantic::Function>()) {
if (current_function_ == func->Declaration()) {
add_error(expr->source(), "v-0004",
"recursion is not allowed: '" +
program_->Symbols().NameFor(current_function_->symbol()) +
"'");
return false;
}
return true;
}
add_error(expr->source(), "Invalid function call expression");
return false;
}
bool ValidatorImpl::ValidateBadAssignmentToIdentifier( bool ValidatorImpl::ValidateBadAssignmentToIdentifier(
const ast::AssignmentStatement* assign) { const ast::AssignmentStatement* assign) {
auto* ident = assign->lhs()->As<ast::IdentifierExpression>(); auto* ident = assign->lhs()->As<ast::IdentifierExpression>();
@ -426,12 +379,7 @@ bool ValidatorImpl::ValidateAssign(const ast::AssignmentStatement* assign) {
} }
auto* lhs = assign->lhs(); auto* lhs = assign->lhs();
auto* rhs = assign->rhs(); auto* rhs = assign->rhs();
if (!ValidateExpression(lhs)) {
return false;
}
if (!ValidateExpression(rhs)) {
return false;
}
// Pointers are not storable in WGSL, but the right-hand side must be // Pointers are not storable in WGSL, but the right-hand side must be
// storable. The raw right-hand side might be a pointer value which must be // storable. The raw right-hand side might be a pointer value which must be
// loaded (dereferenced) to provide the value to be stored. // loaded (dereferenced) to provide the value to be stored.
@ -458,17 +406,6 @@ bool ValidatorImpl::ValidateAssign(const ast::AssignmentStatement* assign) {
return true; return true;
} }
bool ValidatorImpl::ValidateExpression(const ast::Expression* expr) {
if (!expr) {
return false;
}
if (auto* c = expr->As<ast::CallExpression>()) {
return ValidateCallExpr(c);
}
return true;
}
bool ValidatorImpl::IsStorable(type::Type* type) { bool ValidatorImpl::IsStorable(type::Type* type) {
if (type == nullptr) { if (type == nullptr) {
return false; return false;

View File

@ -94,10 +94,6 @@ class ValidatorImpl {
/// @returns true if the LHS of theassignment is not an identifier expression /// @returns true if the LHS of theassignment is not an identifier expression
bool ValidateBadAssignmentToIdentifier( bool ValidateBadAssignmentToIdentifier(
const ast::AssignmentStatement* assign); const ast::AssignmentStatement* assign);
/// Validates an expression
/// @param expr the expression to check
/// @return true if the expression is valid
bool ValidateExpression(const ast::Expression* expr);
/// Validates declaration name uniqueness /// Validates declaration name uniqueness
/// @param decl is the new declaration to be added /// @param decl is the new declaration to be added
/// @returns true if no previous declaration with the `decl` 's name /// @returns true if no previous declaration with the `decl` 's name
@ -107,10 +103,6 @@ class ValidatorImpl {
/// @param ret the return statement to check /// @param ret the return statement to check
/// @returns true if function return type matches the return statement type /// @returns true if function return type matches the return statement type
bool ValidateReturnStatement(const ast::ReturnStatement* ret); bool ValidateReturnStatement(const ast::ReturnStatement* ret);
/// Validates function calls
/// @param expr the call to validate
/// @returns true if successful
bool ValidateCallExpr(const ast::CallExpression* expr);
/// Validates switch statements /// Validates switch statements
/// @param s the switch statement to check /// @param s the switch statement to check
/// @returns true if the valdiation was successful /// @returns true if the valdiation was successful

View File

@ -169,6 +169,7 @@ source_set("tint_unittests_core_src") {
"../src/program_builder_test.cc", "../src/program_builder_test.cc",
"../src/program_test.cc", "../src/program_test.cc",
"../src/resolver/assignment_validation_test.cc", "../src/resolver/assignment_validation_test.cc",
"../src/resolver/builtins_validation_test.cc",
"../src/resolver/decoration_validation_test.cc", "../src/resolver/decoration_validation_test.cc",
"../src/resolver/function_validation_test.cc", "../src/resolver/function_validation_test.cc",
"../src/resolver/host_shareable_validation_test.cc", "../src/resolver/host_shareable_validation_test.cc",
@ -217,7 +218,6 @@ source_set("tint_unittests_core_src") {
"../src/utils/tmpfile.h", "../src/utils/tmpfile.h",
"../src/utils/tmpfile_test.cc", "../src/utils/tmpfile_test.cc",
"../src/utils/unique_vector_test.cc", "../src/utils/unique_vector_test.cc",
"../src/validator/validator_builtins_test.cc",
"../src/validator/validator_control_block_test.cc", "../src/validator/validator_control_block_test.cc",
"../src/validator/validator_decoration_test.cc", "../src/validator/validator_decoration_test.cc",
"../src/validator/validator_function_test.cc", "../src/validator/validator_function_test.cc",