diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 80b49a561c..b223e03115 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -466,6 +466,7 @@ if(${TINT_BUILD_TESTS}) intrinsic_table_test.cc program_test.cc resolver/assignment_validation_test.cc + resolver/builtins_validation_test.cc resolver/decoration_validation_test.cc resolver/function_validation_test.cc resolver/host_shareable_validation_test.cc @@ -509,7 +510,6 @@ if(${TINT_BUILD_TESTS}) utils/tmpfile_test.cc utils/tmpfile.h utils/unique_vector_test.cc - validator/validator_builtins_test.cc validator/validator_control_block_test.cc validator/validator_decoration_test.cc validator/validator_function_test.cc diff --git a/src/validator/validator_builtins_test.cc b/src/resolver/builtins_validation_test.cc similarity index 66% rename from src/validator/validator_builtins_test.cc rename to src/resolver/builtins_validation_test.cc index fa9aedea1e..922e454523 100644 --- a/src/validator/validator_builtins_test.cc +++ b/src/resolver/builtins_validation_test.cc @@ -12,111 +12,91 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/validator/validator_test_helper.h" +#include "src/resolver/resolver_test_helper.h" namespace tint { +namespace { +class ResolverBuiltinsValidationTest : public resolver::TestHelper, + public testing::Test {}; -class ValidatorBuiltinsTest : public ValidatorTestHelper, - public testing::Test {}; - -TEST_F(ValidatorBuiltinsTest, Length_Float_Scalar) { +TEST_F(ResolverBuiltinsValidationTest, Length_Float_Scalar) { auto* builtin = Call("length", 1.0f); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Length_Float_Vec2) { +TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec2) { auto* builtin = Call("length", vec2(1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Length_Float_Vec3) { +TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec3) { auto* builtin = Call("length", vec3(1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Length_Float_Vec4) { +TEST_F(ResolverBuiltinsValidationTest, Length_Float_Vec4) { auto* builtin = Call("length", vec4(1.0f, 1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Distance_Float_Scalar) { +TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Scalar) { auto* builtin = Call("distance", 1.0f, 1.0f); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Distance_Float_Vec2) { +TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec2) { auto* builtin = Call("distance", vec2(1.0f, 1.0f), vec2(1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Distance_Float_Vec3) { +TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec3) { auto* builtin = Call("distance", vec3(1.0f, 1.0f, 1.0f), vec3(1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Distance_Float_Vec4) { +TEST_F(ResolverBuiltinsValidationTest, Distance_Float_Vec4) { auto* builtin = Call("distance", vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4(1.0f, 1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Determinant_Mat2x2) { +TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat2x2) { auto* builtin = Call("determinant", mat2x2(vec2(1.0f, 1.0f), vec2(1.0f, 1.0f))); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Determinant_Mat3x3) { +TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat3x3) { auto* builtin = Call("determinant", mat3x3(vec3(1.0f, 1.0f, 1.0f), vec3(1.0f, 1.0f, 1.0f), vec3(1.0f, 1.0f, 1.0f))); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Determinant_Mat4x4) { +TEST_F(ResolverBuiltinsValidationTest, Determinant_Mat4x4) { auto* builtin = Call("determinant", mat4x4(vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4(1.0f, 1.0f, 1.0f, 1.0f), @@ -124,251 +104,198 @@ TEST_F(ValidatorBuiltinsTest, Determinant_Mat4x4) { vec4(1.0f, 1.0f, 1.0f, 1.0f))); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Frexp_Scalar) { - auto* a = Var("a", ty.i32(), ast::StorageClass::kWorkgroup); - RegisterVariable(a); +TEST_F(ResolverBuiltinsValidationTest, Frexp_Scalar) { + auto* a = Var("a", ty.i32(), ast::StorageClass::kFunction); auto* builtin = Call("frexp", 1.0f, Expr("a")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->Is()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Frexp_Vec2) { - auto* a = Var("a", ty.vec2(), ast::StorageClass::kWorkgroup); +TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec2) { + auto* a = Var("a", ty.vec2(), ast::StorageClass::kFunction); auto* b = Const("b", create(create(ty.i32(), 2), - ast::StorageClass::kWorkgroup), + ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("frexp", vec2(1.0f, 1.0f), Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Frexp_Vec3) { - auto* a = Var("a", ty.vec3(), ast::StorageClass::kWorkgroup); +TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec3) { + auto* a = Var("a", ty.vec3(), ast::StorageClass::kFunction); auto* b = Const("b", create(create(ty.i32(), 3), - ast::StorageClass::kWorkgroup), + ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("frexp", vec3(1.0f, 1.0f, 1.0f), Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Frexp_Vec4) { - auto* a = Var("a", ty.vec4(), ast::StorageClass::kWorkgroup); +TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec4) { + auto* a = Var("a", ty.vec4(), ast::StorageClass::kFunction); auto* b = Const("b", create(create(ty.i32(), 4), - ast::StorageClass::kWorkgroup), + ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("frexp", vec4(1.0f, 1.0f, 1.0f, 1.0f), Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Modf_Scalar) { - auto* a = Var("a", ty.f32(), ast::StorageClass::kWorkgroup); - auto* b = Const("b", ty.pointer(ast::StorageClass::kWorkgroup), +TEST_F(ResolverBuiltinsValidationTest, Modf_Scalar) { + auto* a = Var("a", ty.f32(), ast::StorageClass::kFunction); + auto* b = Const("b", ty.pointer(ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("modf", 1.0f, Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->Is()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Modf_Vec2) { - auto* a = Var("a", ty.vec2(), ast::StorageClass::kWorkgroup); +TEST_F(ResolverBuiltinsValidationTest, Modf_Vec2) { + auto* a = Var("a", ty.vec2(), ast::StorageClass::kFunction); auto* b = Const("b", create(create(ty.f32(), 2), - ast::StorageClass::kWorkgroup), + ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("modf", vec2(1.0f, 1.0f), Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Modf_Vec3) { - auto* a = Var("a", ty.vec3(), ast::StorageClass::kWorkgroup); +TEST_F(ResolverBuiltinsValidationTest, Modf_Vec3) { + auto* a = Var("a", ty.vec3(), ast::StorageClass::kFunction); auto* b = Const("b", create(create(ty.f32(), 3), - ast::StorageClass::kWorkgroup), + ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("modf", vec3(1.0f, 1.0f, 1.0f), Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Modf_Vec4) { - auto* a = Var("a", ty.vec4(), ast::StorageClass::kWorkgroup); +TEST_F(ResolverBuiltinsValidationTest, Modf_Vec4) { + auto* a = Var("a", ty.vec4(), ast::StorageClass::kFunction); auto* b = Const("b", create(create(ty.f32(), 4), - ast::StorageClass::kWorkgroup), + ast::StorageClass::kFunction), Expr("a"), {}); - RegisterVariable(a); - RegisterVariable(b); auto* builtin = Call("modf", vec4(1.0f, 1.0f, 1.0f, 1.0f), Expr("b")); - WrapInFunction(builtin); - - ValidatorImpl& v = Build(); + WrapInFunction(Decl(a), Decl(b), builtin); + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); EXPECT_TRUE(TypeOf(builtin->params()[1])->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } -TEST_F(ValidatorBuiltinsTest, Cross_Float_Vec3) { +TEST_F(ResolverBuiltinsValidationTest, Cross_Float_Vec3) { auto* builtin = Call("cross", vec3(1.0f, 1.0f, 1.0f), vec3(1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Dot_Float_Vec2) { +TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec2) { auto* builtin = Call("dot", vec2(1.0f, 1.0f), vec2(1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Dot_Float_Vec3) { +TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec3) { auto* builtin = Call("dot", vec3(1.0f, 1.0f, 1.0f), vec3(1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Dot_Float_Vec4) { +TEST_F(ResolverBuiltinsValidationTest, Dot_Float_Vec4) { auto* builtin = Call("dot", vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4(1.0f, 1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->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)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Select_Integer_Scalar) { +TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Scalar) { auto* builtin = Call("select", Expr(1), Expr(1), Expr(true)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Select_Boolean_Scalar) { +TEST_F(ResolverBuiltinsValidationTest, Select_Boolean_Scalar) { auto* builtin = Call("select", Expr(true), Expr(true), Expr(true)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Select_Float_Vec2) { +TEST_F(ResolverBuiltinsValidationTest, Select_Float_Vec2) { auto* builtin = Call("select", vec2(1.0f, 1.0f), vec2(1.0f, 1.0f), vec2(true, true)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Select_Integer_Vec2) { +TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Vec2) { auto* builtin = Call("select", vec2(1, 1), vec2(1, 1), vec2(true, true)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ValidatorBuiltinsTest, Select_Boolean_Vec2) { +TEST_F(ResolverBuiltinsValidationTest, Select_Boolean_Vec2) { auto* builtin = Call("select", vec2(true, true), vec2(true, true), vec2(true, true)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } template -class ValidatorBuiltinsTestWithParams : public ValidatorTestHelper, - public testing::TestWithParam {}; +class ResolverBuiltinsValidationTestWithParams + : public resolver::TestHelper, + public testing::TestWithParam {}; using FloatAllMatching = - ValidatorBuiltinsTestWithParams>; + ResolverBuiltinsValidationTestWithParams>; TEST_P(FloatAllMatching, Scalar) { std::string name = std::get<0>(GetParam()); @@ -381,10 +308,8 @@ TEST_P(FloatAllMatching, Scalar) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(FloatAllMatching, Vec2) { @@ -398,10 +323,8 @@ TEST_P(FloatAllMatching, Vec2) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(FloatAllMatching, Vec3) { @@ -415,10 +338,8 @@ TEST_P(FloatAllMatching, Vec3) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_float_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(FloatAllMatching, Vec4) { @@ -432,13 +353,11 @@ TEST_P(FloatAllMatching, Vec4) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); 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, ::testing::Values(std::make_tuple("abs", 1), std::make_tuple("acos", 1), @@ -484,7 +403,7 @@ INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, std::make_tuple("trunc", 1))); using IntegerAllMatching = - ValidatorBuiltinsTestWithParams>; + ResolverBuiltinsValidationTestWithParams>; TEST_P(IntegerAllMatching, ScalarUnsigned) { std::string name = std::get<0>(GetParam()); @@ -497,10 +416,8 @@ TEST_P(IntegerAllMatching, ScalarUnsigned) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, Vec2Unsigned) { @@ -514,10 +431,8 @@ TEST_P(IntegerAllMatching, Vec2Unsigned) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, Vec3Unsigned) { @@ -531,10 +446,8 @@ TEST_P(IntegerAllMatching, Vec3Unsigned) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, Vec4Unsigned) { @@ -548,10 +461,8 @@ TEST_P(IntegerAllMatching, Vec4Unsigned) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_unsigned_integer_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, ScalarSigned) { @@ -565,10 +476,8 @@ TEST_P(IntegerAllMatching, ScalarSigned) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->Is()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, Vec2Signed) { @@ -582,10 +491,8 @@ TEST_P(IntegerAllMatching, Vec2Signed) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, Vec3Signed) { @@ -599,10 +506,8 @@ TEST_P(IntegerAllMatching, Vec3Signed) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(TypeOf(builtin)->is_signed_integer_vector()); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); } TEST_P(IntegerAllMatching, Vec4Signed) { @@ -616,13 +521,11 @@ TEST_P(IntegerAllMatching, Vec4Signed) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - + EXPECT_TRUE(r()->Resolve()) << r()->error(); 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, ::testing::Values(std::make_tuple("abs", 1), std::make_tuple("clamp", 3), @@ -632,7 +535,7 @@ INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, std::make_tuple("reverseBits", 1))); using BooleanVectorInput = - ValidatorBuiltinsTestWithParams>; + ResolverBuiltinsValidationTestWithParams>; TEST_P(BooleanVectorInput, Vec2) { std::string name = std::get<0>(GetParam()); @@ -645,9 +548,7 @@ TEST_P(BooleanVectorInput, Vec2) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } TEST_P(BooleanVectorInput, Vec3) { @@ -661,9 +562,7 @@ TEST_P(BooleanVectorInput, Vec3) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } TEST_P(BooleanVectorInput, Vec4) { @@ -677,44 +576,41 @@ TEST_P(BooleanVectorInput, Vec4) { auto* builtin = Call(name, params); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, +INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest, BooleanVectorInput, ::testing::Values(std::make_tuple("all", 1), std::make_tuple("any", 1))); -using DataPacking4x8 = ValidatorBuiltinsTestWithParams; +using DataPacking4x8 = ResolverBuiltinsValidationTestWithParams; TEST_P(DataPacking4x8, Float_Vec4) { auto name = GetParam(); auto* builtin = Call(name, vec4(1.0f, 1.0f, 1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, +INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest, DataPacking4x8, ::testing::Values("pack4x8snorm", "pack4x8unorm")); -using DataPacking2x16 = ValidatorBuiltinsTestWithParams; +using DataPacking2x16 = ResolverBuiltinsValidationTestWithParams; TEST_P(DataPacking2x16, Float_Vec2) { auto name = GetParam(); auto* builtin = Call(name, vec2(1.0f, 1.0f)); WrapInFunction(builtin); - ValidatorImpl& v = Build(); - EXPECT_TRUE(v.ValidateCallExpr(builtin)) << v.error(); + EXPECT_TRUE(r()->Resolve()) << r()->error(); } -INSTANTIATE_TEST_SUITE_P(ValidatorBuiltinsTest, +INSTANTIATE_TEST_SUITE_P(ResolverBuiltinsValidationTest, DataPacking2x16, ::testing::Values("pack2x16snorm", "pack2x16unorm", "pack2x16float")); +} // namespace } // namespace tint diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc index 3b43fc1f68..fa5a25f5fc 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -582,7 +582,8 @@ bool Resolver::Call(ast::CallExpression* call) { auto callee_func_it = symbol_to_function_.find(ident->symbol()); if (callee_func_it == symbol_to_function_.end()) { 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.", call->source()); } else { @@ -637,39 +638,6 @@ bool Resolver::IntrinsicCall(ast::CallExpression* call, if (!result.intrinsic) { // Intrinsic lookup failed. 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(); - break; - case IntrinsicType::kDeterminant: - ret_ty = builder_->create(); - break; - case IntrinsicType::kArrayLength: - ret_ty = builder_->create(); - break; - default: - ret_ty = arg_tys.empty() ? builder_->ty.void_() : arg_tys[0]; - break; - } - auto* intrinsic = builder_->create(intrinsic_type, - ret_ty, parameters); - builder_->Sem().Add(call, builder_->create( - call, intrinsic, current_statement_)); - SetType(call, ret_ty); return false; } diff --git a/src/resolver/validation_test.cc b/src/resolver/validation_test.cc index 30c5ba96f0..8536a22a38 100644 --- a/src/resolver/validation_test.cc +++ b/src/resolver/validation_test.cc @@ -127,7 +127,8 @@ TEST_F(ResolverValidationTest, Stmt_Call_recursive) { EXPECT_FALSE(r()->Resolve()); 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."); } diff --git a/src/validator/validator_impl.cc b/src/validator/validator_impl.cc index 021456cb02..65e2a33400 100644 --- a/src/validator/validator_impl.cc +++ b/src/validator/validator_impl.cc @@ -257,12 +257,7 @@ bool ValidatorImpl::ValidateStatement(const ast::Statement* stmt) { return false; } if (auto* v = stmt->As()) { - bool constructor_valid = - v->variable()->has_constructor() - ? ValidateExpression(v->variable()->constructor()) - : true; - - return constructor_valid && ValidateDeclStatement(v); + return ValidateDeclStatement(v); } if (auto* a = stmt->As()) { return ValidateAssign(a); @@ -270,9 +265,6 @@ bool ValidatorImpl::ValidateStatement(const ast::Statement* stmt) { if (auto* r = stmt->As()) { return ValidateReturnStatement(r); } - if (auto* c = stmt->As()) { - return ValidateCallExpr(c->expr()); - } if (auto* s = stmt->As()) { return ValidateSwitch(s); } @@ -286,10 +278,6 @@ bool ValidatorImpl::ValidateStatement(const ast::Statement* stmt) { } bool ValidatorImpl::ValidateSwitch(const ast::SwitchStatement* s) { - if (!ValidateExpression(s->condition())) { - return false; - } - auto* cond_type = program_->Sem().Get(s->condition())->Type()->UnwrapAll(); if (!cond_type->is_integer_scalar()) { add_error(s->condition()->source(), "v-0025", @@ -358,41 +346,6 @@ bool ValidatorImpl::ValidateCase(const ast::CaseStatement* c) { 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()) { - // TODO(bclayton): Add intrinsic validation checks here. - return true; - } - - if (auto* func = target->As()) { - 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( const ast::AssignmentStatement* assign) { auto* ident = assign->lhs()->As(); @@ -426,12 +379,7 @@ bool ValidatorImpl::ValidateAssign(const ast::AssignmentStatement* assign) { } auto* lhs = assign->lhs(); 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 // storable. The raw right-hand side might be a pointer value which must be // loaded (dereferenced) to provide the value to be stored. @@ -458,17 +406,6 @@ bool ValidatorImpl::ValidateAssign(const ast::AssignmentStatement* assign) { return true; } -bool ValidatorImpl::ValidateExpression(const ast::Expression* expr) { - if (!expr) { - return false; - } - - if (auto* c = expr->As()) { - return ValidateCallExpr(c); - } - return true; -} - bool ValidatorImpl::IsStorable(type::Type* type) { if (type == nullptr) { return false; diff --git a/src/validator/validator_impl.h b/src/validator/validator_impl.h index 102fb4bb7c..2ec4c22e26 100644 --- a/src/validator/validator_impl.h +++ b/src/validator/validator_impl.h @@ -94,10 +94,6 @@ class ValidatorImpl { /// @returns true if the LHS of theassignment is not an identifier expression bool ValidateBadAssignmentToIdentifier( 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 /// @param decl is the new declaration to be added /// @returns true if no previous declaration with the `decl` 's name @@ -107,10 +103,6 @@ class ValidatorImpl { /// @param ret the return statement to check /// @returns true if function return type matches the return statement type 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 /// @param s the switch statement to check /// @returns true if the valdiation was successful diff --git a/test/BUILD.gn b/test/BUILD.gn index 735e85cdaf..07ff399360 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -169,6 +169,7 @@ source_set("tint_unittests_core_src") { "../src/program_builder_test.cc", "../src/program_test.cc", "../src/resolver/assignment_validation_test.cc", + "../src/resolver/builtins_validation_test.cc", "../src/resolver/decoration_validation_test.cc", "../src/resolver/function_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_test.cc", "../src/utils/unique_vector_test.cc", - "../src/validator/validator_builtins_test.cc", "../src/validator/validator_control_block_test.cc", "../src/validator/validator_decoration_test.cc", "../src/validator/validator_function_test.cc",