blob: b02cf7d87c1eb14aa54aa2ab4a93be1cc2eee57d [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/tint/ast/bitcast_expression.h"
16#include "src/tint/resolver/resolver.h"
17#include "src/tint/resolver/resolver_test_helper.h"
18
19#include "gmock/gmock.h"
20
dan sinclaird2093792022-04-07 17:45:45 +000021namespace tint::resolver {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000022namespace {
23
24struct Type {
dan sinclair41e4d9a2022-05-01 14:40:55 +000025 template <typename T>
26 static constexpr Type Create() {
27 return Type{builder::DataType<T>::AST, builder::DataType<T>::Sem,
Antonio Maioranob6d524382022-08-31 22:59:08 +000028 builder::DataType<T>::ExprFromDouble};
dan sinclair41e4d9a2022-05-01 14:40:55 +000029 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000030
dan sinclair41e4d9a2022-05-01 14:40:55 +000031 builder::ast_type_func_ptr ast;
32 builder::sem_type_func_ptr sem;
Antonio Maioranob6d524382022-08-31 22:59:08 +000033 builder::ast_expr_from_double_func_ptr expr;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000034};
35
36static constexpr Type kNumericScalars[] = {
Ben Clayton0ce9ab02022-05-05 20:23:40 +000037 Type::Create<f32>(),
38 Type::Create<i32>(),
39 Type::Create<u32>(),
Ryan Harrisondbc13af2022-02-21 15:19:07 +000040};
41static constexpr Type kVec2NumericScalars[] = {
Ben Clayton0ce9ab02022-05-05 20:23:40 +000042 Type::Create<builder::vec2<f32>>(),
43 Type::Create<builder::vec2<i32>>(),
44 Type::Create<builder::vec2<u32>>(),
Ryan Harrisondbc13af2022-02-21 15:19:07 +000045};
46static constexpr Type kVec3NumericScalars[] = {
Ben Clayton0ce9ab02022-05-05 20:23:40 +000047 Type::Create<builder::vec3<f32>>(),
48 Type::Create<builder::vec3<i32>>(),
49 Type::Create<builder::vec3<u32>>(),
Ryan Harrisondbc13af2022-02-21 15:19:07 +000050};
51static constexpr Type kVec4NumericScalars[] = {
Ben Clayton0ce9ab02022-05-05 20:23:40 +000052 Type::Create<builder::vec4<f32>>(),
53 Type::Create<builder::vec4<i32>>(),
54 Type::Create<builder::vec4<u32>>(),
Ryan Harrisondbc13af2022-02-21 15:19:07 +000055};
56static constexpr Type kInvalid[] = {
57 // A non-exhaustive selection of uncastable types
58 Type::Create<bool>(),
59 Type::Create<builder::vec2<bool>>(),
60 Type::Create<builder::vec3<bool>>(),
61 Type::Create<builder::vec4<bool>>(),
Ben Clayton0ce9ab02022-05-05 20:23:40 +000062 Type::Create<builder::array<2, i32>>(),
63 Type::Create<builder::array<3, u32>>(),
64 Type::Create<builder::array<4, f32>>(),
Ryan Harrisondbc13af2022-02-21 15:19:07 +000065 Type::Create<builder::array<5, bool>>(),
Ben Clayton0ce9ab02022-05-05 20:23:40 +000066 Type::Create<builder::mat2x2<f32>>(),
67 Type::Create<builder::mat3x3<f32>>(),
68 Type::Create<builder::mat4x4<f32>>(),
69 Type::Create<builder::ptr<i32>>(),
70 Type::Create<builder::ptr<builder::array<2, i32>>>(),
71 Type::Create<builder::ptr<builder::mat2x2<f32>>>(),
Ryan Harrisondbc13af2022-02-21 15:19:07 +000072};
73
dan sinclair41e4d9a2022-05-01 14:40:55 +000074using ResolverBitcastValidationTest = ResolverTestWithParam<std::tuple<Type, Type>>;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000075
76////////////////////////////////////////////////////////////////////////////////
77// Valid bitcasts
78////////////////////////////////////////////////////////////////////////////////
79using ResolverBitcastValidationTestPass = ResolverBitcastValidationTest;
80TEST_P(ResolverBitcastValidationTestPass, Test) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000081 auto src = std::get<0>(GetParam());
82 auto dst = std::get<1>(GetParam());
Ryan Harrisondbc13af2022-02-21 15:19:07 +000083
dan sinclair41e4d9a2022-05-01 14:40:55 +000084 auto* cast = Bitcast(dst.ast(*this), src.expr(*this, 0));
85 WrapInFunction(cast);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000086
dan sinclair41e4d9a2022-05-01 14:40:55 +000087 ASSERT_TRUE(r()->Resolve()) << r()->error();
88 EXPECT_EQ(TypeOf(cast), dst.sem(*this));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000089}
90INSTANTIATE_TEST_SUITE_P(Scalars,
91 ResolverBitcastValidationTestPass,
92 testing::Combine(testing::ValuesIn(kNumericScalars),
93 testing::ValuesIn(kNumericScalars)));
dan sinclair41e4d9a2022-05-01 14:40:55 +000094INSTANTIATE_TEST_SUITE_P(Vec2,
95 ResolverBitcastValidationTestPass,
96 testing::Combine(testing::ValuesIn(kVec2NumericScalars),
97 testing::ValuesIn(kVec2NumericScalars)));
98INSTANTIATE_TEST_SUITE_P(Vec3,
99 ResolverBitcastValidationTestPass,
100 testing::Combine(testing::ValuesIn(kVec3NumericScalars),
101 testing::ValuesIn(kVec3NumericScalars)));
102INSTANTIATE_TEST_SUITE_P(Vec4,
103 ResolverBitcastValidationTestPass,
104 testing::Combine(testing::ValuesIn(kVec4NumericScalars),
105 testing::ValuesIn(kVec4NumericScalars)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000106
107////////////////////////////////////////////////////////////////////////////////
108// Invalid source type for bitcasts
109////////////////////////////////////////////////////////////////////////////////
110using ResolverBitcastValidationTestInvalidSrcTy = ResolverBitcastValidationTest;
111TEST_P(ResolverBitcastValidationTestInvalidSrcTy, Test) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000112 auto src = std::get<0>(GetParam());
113 auto dst = std::get<1>(GetParam());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000114
dan sinclair41e4d9a2022-05-01 14:40:55 +0000115 auto* cast = Bitcast(dst.ast(*this), Expr(Source{{12, 34}}, "src"));
Ben Clayton58794ae2022-08-19 17:28:53 +0000116 WrapInFunction(Let("src", src.expr(*this, 0)), cast);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000117
dan sinclair41e4d9a2022-05-01 14:40:55 +0000118 auto expected =
119 "12:34 error: '" + src.sem(*this)->FriendlyName(Symbols()) + "' cannot be bitcast";
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000120
dan sinclair41e4d9a2022-05-01 14:40:55 +0000121 EXPECT_FALSE(r()->Resolve());
122 EXPECT_EQ(r()->error(), expected);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000123}
124INSTANTIATE_TEST_SUITE_P(Scalars,
125 ResolverBitcastValidationTestInvalidSrcTy,
126 testing::Combine(testing::ValuesIn(kInvalid),
127 testing::ValuesIn(kNumericScalars)));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000128INSTANTIATE_TEST_SUITE_P(Vec2,
129 ResolverBitcastValidationTestInvalidSrcTy,
130 testing::Combine(testing::ValuesIn(kInvalid),
131 testing::ValuesIn(kVec2NumericScalars)));
132INSTANTIATE_TEST_SUITE_P(Vec3,
133 ResolverBitcastValidationTestInvalidSrcTy,
134 testing::Combine(testing::ValuesIn(kInvalid),
135 testing::ValuesIn(kVec3NumericScalars)));
136INSTANTIATE_TEST_SUITE_P(Vec4,
137 ResolverBitcastValidationTestInvalidSrcTy,
138 testing::Combine(testing::ValuesIn(kInvalid),
139 testing::ValuesIn(kVec4NumericScalars)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000140
141////////////////////////////////////////////////////////////////////////////////
142// Invalid target type for bitcasts
143////////////////////////////////////////////////////////////////////////////////
144using ResolverBitcastValidationTestInvalidDstTy = ResolverBitcastValidationTest;
145TEST_P(ResolverBitcastValidationTestInvalidDstTy, Test) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000146 auto src = std::get<0>(GetParam());
147 auto dst = std::get<1>(GetParam());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000148
dan sinclair41e4d9a2022-05-01 14:40:55 +0000149 // Use an alias so we can put a Source on the bitcast type
150 Alias("T", dst.ast(*this));
Ben Clayton2117f802023-02-03 14:01:43 +0000151 WrapInFunction(Bitcast(ty(Source{{12, 34}}, "T"), src.expr(*this, 0)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000152
dan sinclair41e4d9a2022-05-01 14:40:55 +0000153 auto expected =
154 "12:34 error: cannot bitcast to '" + dst.sem(*this)->FriendlyName(Symbols()) + "'";
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000155
dan sinclair41e4d9a2022-05-01 14:40:55 +0000156 EXPECT_FALSE(r()->Resolve());
157 EXPECT_EQ(r()->error(), expected);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000158}
159INSTANTIATE_TEST_SUITE_P(Scalars,
160 ResolverBitcastValidationTestInvalidDstTy,
161 testing::Combine(testing::ValuesIn(kNumericScalars),
162 testing::ValuesIn(kInvalid)));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000163INSTANTIATE_TEST_SUITE_P(Vec2,
164 ResolverBitcastValidationTestInvalidDstTy,
165 testing::Combine(testing::ValuesIn(kVec2NumericScalars),
166 testing::ValuesIn(kInvalid)));
167INSTANTIATE_TEST_SUITE_P(Vec3,
168 ResolverBitcastValidationTestInvalidDstTy,
169 testing::Combine(testing::ValuesIn(kVec3NumericScalars),
170 testing::ValuesIn(kInvalid)));
171INSTANTIATE_TEST_SUITE_P(Vec4,
172 ResolverBitcastValidationTestInvalidDstTy,
173 testing::Combine(testing::ValuesIn(kVec4NumericScalars),
174 testing::ValuesIn(kInvalid)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000175
176////////////////////////////////////////////////////////////////////////////////
177// Incompatible bitcast, but both src and dst types are valid
178////////////////////////////////////////////////////////////////////////////////
179using ResolverBitcastValidationTestIncompatible = ResolverBitcastValidationTest;
180TEST_P(ResolverBitcastValidationTestIncompatible, Test) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000181 auto src = std::get<0>(GetParam());
182 auto dst = std::get<1>(GetParam());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000183
dan sinclair41e4d9a2022-05-01 14:40:55 +0000184 WrapInFunction(Bitcast(Source{{12, 34}}, dst.ast(*this), src.expr(*this, 0)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000185
dan sinclair41e4d9a2022-05-01 14:40:55 +0000186 auto expected = "12:34 error: cannot bitcast from '" + src.sem(*this)->FriendlyName(Symbols()) +
187 "' to '" + dst.sem(*this)->FriendlyName(Symbols()) + "'";
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000188
dan sinclair41e4d9a2022-05-01 14:40:55 +0000189 EXPECT_FALSE(r()->Resolve());
190 EXPECT_EQ(r()->error(), expected);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000191}
dan sinclair41e4d9a2022-05-01 14:40:55 +0000192INSTANTIATE_TEST_SUITE_P(ScalarToVec2,
193 ResolverBitcastValidationTestIncompatible,
194 testing::Combine(testing::ValuesIn(kNumericScalars),
195 testing::ValuesIn(kVec2NumericScalars)));
196INSTANTIATE_TEST_SUITE_P(Vec2ToVec3,
197 ResolverBitcastValidationTestIncompatible,
198 testing::Combine(testing::ValuesIn(kVec2NumericScalars),
199 testing::ValuesIn(kVec3NumericScalars)));
200INSTANTIATE_TEST_SUITE_P(Vec3ToVec4,
201 ResolverBitcastValidationTestIncompatible,
202 testing::Combine(testing::ValuesIn(kVec3NumericScalars),
203 testing::ValuesIn(kVec4NumericScalars)));
204INSTANTIATE_TEST_SUITE_P(Vec4ToScalar,
205 ResolverBitcastValidationTestIncompatible,
206 testing::Combine(testing::ValuesIn(kVec4NumericScalars),
207 testing::ValuesIn(kNumericScalars)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000208
209} // namespace
dan sinclaird2093792022-04-07 17:45:45 +0000210} // namespace tint::resolver