text_literal_test.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // Copyright (c) 2015-2016 The Khronos Group Inc.
  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. #include <string>
  15. #include <utility>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "test/test_fixture.h"
  19. #include "test/unit_spirv.h"
  20. namespace spvtools {
  21. namespace {
  22. using ::testing::Eq;
  23. TEST(TextLiteral, GoodI32) {
  24. spv_literal_t l;
  25. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("-0", &l));
  26. EXPECT_EQ(SPV_LITERAL_TYPE_INT_32, l.type);
  27. EXPECT_EQ(0, l.value.i32);
  28. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("-2147483648", &l));
  29. EXPECT_EQ(SPV_LITERAL_TYPE_INT_32, l.type);
  30. EXPECT_EQ((-2147483647L - 1), l.value.i32);
  31. }
  32. TEST(TextLiteral, GoodU32) {
  33. spv_literal_t l;
  34. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("0", &l));
  35. EXPECT_EQ(SPV_LITERAL_TYPE_UINT_32, l.type);
  36. EXPECT_EQ(0, l.value.i32);
  37. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("4294967295", &l));
  38. EXPECT_EQ(SPV_LITERAL_TYPE_UINT_32, l.type);
  39. EXPECT_EQ(4294967295, l.value.u32);
  40. }
  41. TEST(TextLiteral, GoodI64) {
  42. spv_literal_t l;
  43. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("-2147483649", &l));
  44. EXPECT_EQ(SPV_LITERAL_TYPE_INT_64, l.type);
  45. EXPECT_EQ(-2147483649LL, l.value.i64);
  46. }
  47. TEST(TextLiteral, GoodU64) {
  48. spv_literal_t l;
  49. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("4294967296", &l));
  50. EXPECT_EQ(SPV_LITERAL_TYPE_UINT_64, l.type);
  51. EXPECT_EQ(4294967296u, l.value.u64);
  52. }
  53. TEST(TextLiteral, GoodFloat) {
  54. spv_literal_t l;
  55. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("1.0", &l));
  56. EXPECT_EQ(SPV_LITERAL_TYPE_FLOAT_32, l.type);
  57. EXPECT_EQ(1.0, l.value.f);
  58. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("1.5", &l));
  59. EXPECT_EQ(SPV_LITERAL_TYPE_FLOAT_32, l.type);
  60. EXPECT_EQ(1.5, l.value.f);
  61. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral("-.25", &l));
  62. EXPECT_EQ(SPV_LITERAL_TYPE_FLOAT_32, l.type);
  63. EXPECT_EQ(-.25, l.value.f);
  64. }
  65. TEST(TextLiteral, BadString) {
  66. spv_literal_t l;
  67. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("", &l));
  68. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("-", &l));
  69. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("--", &l));
  70. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("1-2", &l));
  71. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("123a", &l));
  72. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("12.2.3", &l));
  73. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("\"", &l));
  74. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("\"z", &l));
  75. EXPECT_EQ(SPV_FAILED_MATCH, spvTextToLiteral("a\"", &l));
  76. }
  77. class GoodStringTest
  78. : public ::testing::TestWithParam<std::pair<const char*, const char*>> {};
  79. TEST_P(GoodStringTest, GoodStrings) {
  80. spv_literal_t l;
  81. ASSERT_EQ(SPV_SUCCESS, spvTextToLiteral(std::get<0>(GetParam()), &l));
  82. EXPECT_EQ(SPV_LITERAL_TYPE_STRING, l.type);
  83. EXPECT_EQ(std::get<1>(GetParam()), l.str);
  84. }
  85. INSTANTIATE_TEST_SUITE_P(
  86. TextLiteral, GoodStringTest,
  87. ::testing::ValuesIn(std::vector<std::pair<const char*, const char*>>{
  88. {R"("-")", "-"},
  89. {R"("--")", "--"},
  90. {R"("1-2")", "1-2"},
  91. {R"("123a")", "123a"},
  92. {R"("12.2.3")", "12.2.3"},
  93. {R"("\"")", "\""},
  94. {R"("\\")", "\\"},
  95. {"\"\\foo\nbar\"", "foo\nbar"},
  96. {"\"\\foo\\\nbar\"", "foo\nbar"},
  97. {"\"\xE4\xBA\xB2\"", "\xE4\xBA\xB2"},
  98. {"\"\\\xE4\xBA\xB2\"", "\xE4\xBA\xB2"},
  99. {"\"this \\\" and this \\\\ and \\\xE4\xBA\xB2\"",
  100. "this \" and this \\ and \xE4\xBA\xB2"}}));
  101. TEST(TextLiteral, StringTooLong) {
  102. spv_literal_t l;
  103. std::string too_long =
  104. std::string("\"") +
  105. std::string(SPV_LIMIT_LITERAL_STRING_BYTES_MAX + 1, 'a') + "\"";
  106. EXPECT_EQ(SPV_ERROR_OUT_OF_MEMORY, spvTextToLiteral(too_long.data(), &l));
  107. }
  108. TEST(TextLiteral, GoodLongString) {
  109. spv_literal_t l;
  110. // The universal limit of 65535 Unicode characters might make this
  111. // fail validation, since SPV_LIMIT_LITERAL_STRING_BYTES_MAX is 4*65535.
  112. // However, as an implementation detail, we'll allow the assembler
  113. // to parse it. Otherwise we'd have to scan the string for valid UTF-8
  114. // characters.
  115. std::string unquoted(SPV_LIMIT_LITERAL_STRING_BYTES_MAX, 'a');
  116. std::string good_long = std::string("\"") + unquoted + "\"";
  117. EXPECT_EQ(SPV_SUCCESS, spvTextToLiteral(good_long.data(), &l));
  118. EXPECT_EQ(SPV_LITERAL_TYPE_STRING, l.type);
  119. EXPECT_EQ(unquoted.data(), l.str);
  120. }
  121. TEST(TextLiteral, GoodUTF8String) {
  122. const std::string unquoted =
  123. spvtest::MakeLongUTF8String(SPV_LIMIT_LITERAL_STRING_UTF8_CHARS_MAX);
  124. const std::string good_long = std::string("\"") + unquoted + "\"";
  125. spv_literal_t l;
  126. EXPECT_EQ(SPV_SUCCESS, spvTextToLiteral(good_long.data(), &l));
  127. EXPECT_EQ(SPV_LITERAL_TYPE_STRING, l.type);
  128. EXPECT_EQ(unquoted.data(), l.str);
  129. }
  130. // A test case for parsing literal numbers.
  131. struct TextLiteralCase {
  132. uint32_t bitwidth;
  133. const char* text;
  134. bool is_signed;
  135. bool success;
  136. std::vector<uint32_t> expected_values;
  137. };
  138. using IntegerTest =
  139. spvtest::TextToBinaryTestBase<::testing::TestWithParam<TextLiteralCase>>;
  140. std::vector<uint32_t> successfulEncode(const TextLiteralCase& test,
  141. IdTypeClass type) {
  142. spv_instruction_t inst;
  143. std::string message;
  144. auto capture_message = [&message](spv_message_level_t, const char*,
  145. const spv_position_t&,
  146. const char* m) { message = m; };
  147. IdType expected_type{test.bitwidth, test.is_signed, type};
  148. EXPECT_EQ(SPV_SUCCESS,
  149. AssemblyContext(nullptr, capture_message)
  150. .binaryEncodeNumericLiteral(test.text, SPV_ERROR_INVALID_TEXT,
  151. expected_type, &inst))
  152. << message;
  153. return inst.words;
  154. }
  155. std::string failedEncode(const TextLiteralCase& test, IdTypeClass type) {
  156. spv_instruction_t inst;
  157. std::string message;
  158. auto capture_message = [&message](spv_message_level_t, const char*,
  159. const spv_position_t&,
  160. const char* m) { message = m; };
  161. IdType expected_type{test.bitwidth, test.is_signed, type};
  162. EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
  163. AssemblyContext(nullptr, capture_message)
  164. .binaryEncodeNumericLiteral(test.text, SPV_ERROR_INVALID_TEXT,
  165. expected_type, &inst));
  166. return message;
  167. }
  168. TEST_P(IntegerTest, IntegerBounds) {
  169. if (GetParam().success) {
  170. EXPECT_THAT(successfulEncode(GetParam(), IdTypeClass::kScalarIntegerType),
  171. Eq(GetParam().expected_values));
  172. } else {
  173. std::stringstream ss;
  174. ss << "Integer " << GetParam().text << " does not fit in a "
  175. << GetParam().bitwidth << "-bit "
  176. << (GetParam().is_signed ? "signed" : "unsigned") << " integer";
  177. EXPECT_THAT(failedEncode(GetParam(), IdTypeClass::kScalarIntegerType),
  178. Eq(ss.str()));
  179. }
  180. }
  181. // Four nicely named methods for making TextLiteralCase values.
  182. // Their names have underscores in some places to make it easier
  183. // to read the table that follows.
  184. TextLiteralCase Make_Ok__Signed(uint32_t bitwidth, const char* text,
  185. std::vector<uint32_t> encoding) {
  186. return TextLiteralCase{bitwidth, text, true, true, encoding};
  187. }
  188. TextLiteralCase Make_Ok__Unsigned(uint32_t bitwidth, const char* text,
  189. std::vector<uint32_t> encoding) {
  190. return TextLiteralCase{bitwidth, text, false, true, encoding};
  191. }
  192. TextLiteralCase Make_Bad_Signed(uint32_t bitwidth, const char* text) {
  193. return TextLiteralCase{bitwidth, text, true, false, {}};
  194. }
  195. TextLiteralCase Make_Bad_Unsigned(uint32_t bitwidth, const char* text) {
  196. return TextLiteralCase{bitwidth, text, false, false, {}};
  197. }
  198. // clang-format off
  199. INSTANTIATE_TEST_SUITE_P(
  200. DecimalIntegers, IntegerTest,
  201. ::testing::ValuesIn(std::vector<TextLiteralCase>{
  202. // Check max value and overflow value for 1-bit numbers.
  203. Make_Ok__Signed(1, "0", {0}),
  204. Make_Ok__Unsigned(1, "1", {1}),
  205. Make_Bad_Signed(1, "1"),
  206. Make_Bad_Unsigned(1, "2"),
  207. // Check max value and overflow value for 2-bit numbers.
  208. Make_Ok__Signed(2, "1", {1}),
  209. Make_Ok__Unsigned(2, "3", {3}),
  210. Make_Bad_Signed(2, "2"),
  211. Make_Bad_Unsigned(2, "4"),
  212. // Check max negative value and overflow value for signed
  213. // 1- and 2-bit numbers. Signed negative numbers are sign-extended.
  214. Make_Ok__Signed(1, "-0", {uint32_t(0)}),
  215. Make_Ok__Signed(1, "-1", {uint32_t(-1)}),
  216. Make_Ok__Signed(2, "-0", {0}),
  217. Make_Ok__Signed(2, "-1", {uint32_t(-1)}),
  218. Make_Ok__Signed(2, "-2", {uint32_t(-2)}),
  219. Make_Bad_Signed(2, "-3"),
  220. Make_Bad_Unsigned(2, "2224323424242424"),
  221. Make_Ok__Unsigned(16, "65535", {0xFFFF}),
  222. Make_Bad_Unsigned(16, "65536"),
  223. Make_Bad_Signed(16, "65535"),
  224. Make_Ok__Signed(16, "32767", {0x7FFF}),
  225. Make_Ok__Signed(16, "-32768", {0xFFFF8000}),
  226. // Check values around 32-bits in magnitude.
  227. Make_Ok__Unsigned(33, "4294967296", {0, 1}),
  228. Make_Ok__Unsigned(33, "4294967297", {1, 1}),
  229. Make_Bad_Unsigned(33, "8589934592"),
  230. Make_Bad_Signed(33, "4294967296"),
  231. Make_Ok__Signed(33, "-4294967296", {0x0, 0xFFFFFFFF}),
  232. Make_Ok__Unsigned(64, "4294967296", {0, 1}),
  233. Make_Ok__Unsigned(64, "4294967297", {1, 1}),
  234. // Check max value and overflow value for 64-bit numbers.
  235. Make_Ok__Signed(64, "9223372036854775807", {0xffffffff, 0x7fffffff}),
  236. Make_Bad_Signed(64, "9223372036854775808"),
  237. Make_Ok__Unsigned(64, "9223372036854775808", {0x00000000, 0x80000000}),
  238. Make_Ok__Unsigned(64, "18446744073709551615", {0xffffffff, 0xffffffff}),
  239. Make_Ok__Signed(64, "-9223372036854775808", {0x00000000, 0x80000000}),
  240. }));
  241. // clang-format on
  242. using IntegerLeadingMinusTest =
  243. spvtest::TextToBinaryTestBase<::testing::TestWithParam<TextLiteralCase>>;
  244. TEST_P(IntegerLeadingMinusTest, CantHaveLeadingMinusOnUnsigned) {
  245. EXPECT_FALSE(GetParam().success);
  246. EXPECT_THAT(failedEncode(GetParam(), IdTypeClass::kScalarIntegerType),
  247. Eq("Cannot put a negative number in an unsigned literal"));
  248. }
  249. // clang-format off
  250. INSTANTIATE_TEST_SUITE_P(
  251. DecimalAndHexIntegers, IntegerLeadingMinusTest,
  252. ::testing::ValuesIn(std::vector<TextLiteralCase>{
  253. // Unsigned numbers never allow a leading minus sign.
  254. Make_Bad_Unsigned(16, "-0"),
  255. Make_Bad_Unsigned(16, "-0x0"),
  256. Make_Bad_Unsigned(16, "-0x1"),
  257. Make_Bad_Unsigned(32, "-0"),
  258. Make_Bad_Unsigned(32, "-0x0"),
  259. Make_Bad_Unsigned(32, "-0x1"),
  260. Make_Bad_Unsigned(64, "-0"),
  261. Make_Bad_Unsigned(64, "-0x0"),
  262. Make_Bad_Unsigned(64, "-0x1"),
  263. }));
  264. // clang-format off
  265. INSTANTIATE_TEST_SUITE_P(
  266. HexIntegers, IntegerTest,
  267. ::testing::ValuesIn(std::vector<TextLiteralCase>{
  268. // Check 0x and 0X prefices.
  269. Make_Ok__Signed(16, "0x1234", {0x1234}),
  270. Make_Ok__Signed(16, "0X1234", {0x1234}),
  271. // Check 1-bit numbers
  272. Make_Ok__Signed(1, "0x0", {0}),
  273. Make_Ok__Signed(1, "0x1", {uint32_t(-1)}),
  274. Make_Ok__Unsigned(1, "0x0", {0}),
  275. Make_Ok__Unsigned(1, "0x1", {1}),
  276. Make_Bad_Signed(1, "0x2"),
  277. Make_Bad_Unsigned(1, "0x2"),
  278. // Check 2-bit numbers
  279. Make_Ok__Signed(2, "0x0", {0}),
  280. Make_Ok__Signed(2, "0x1", {1}),
  281. Make_Ok__Signed(2, "0x2", {uint32_t(-2)}),
  282. Make_Ok__Signed(2, "0x3", {uint32_t(-1)}),
  283. Make_Ok__Unsigned(2, "0x0", {0}),
  284. Make_Ok__Unsigned(2, "0x1", {1}),
  285. Make_Ok__Unsigned(2, "0x2", {2}),
  286. Make_Ok__Unsigned(2, "0x3", {3}),
  287. Make_Bad_Signed(2, "0x4"),
  288. Make_Bad_Unsigned(2, "0x4"),
  289. // Check 8-bit numbers
  290. Make_Ok__Signed(8, "0x7f", {0x7f}),
  291. Make_Ok__Signed(8, "0x80", {0xffffff80}),
  292. Make_Ok__Unsigned(8, "0x80", {0x80}),
  293. Make_Ok__Unsigned(8, "0xff", {0xff}),
  294. Make_Bad_Signed(8, "0x100"),
  295. Make_Bad_Unsigned(8, "0x100"),
  296. // Check 16-bit numbers
  297. Make_Ok__Signed(16, "0x7fff", {0x7fff}),
  298. Make_Ok__Signed(16, "0x8000", {0xffff8000}),
  299. Make_Ok__Unsigned(16, "0x8000", {0x8000}),
  300. Make_Ok__Unsigned(16, "0xffff", {0xffff}),
  301. Make_Bad_Signed(16, "0x10000"),
  302. Make_Bad_Unsigned(16, "0x10000"),
  303. // Check 32-bit numbers
  304. Make_Ok__Signed(32, "0x7fffffff", {0x7fffffff}),
  305. Make_Ok__Signed(32, "0x80000000", {0x80000000}),
  306. Make_Ok__Unsigned(32, "0x80000000", {0x80000000}),
  307. Make_Ok__Unsigned(32, "0xffffffff", {0xffffffff}),
  308. Make_Bad_Signed(32, "0x100000000"),
  309. Make_Bad_Unsigned(32, "0x100000000"),
  310. // Check 48-bit numbers
  311. Make_Ok__Unsigned(48, "0x7ffffffff", {0xffffffff, 7}),
  312. Make_Ok__Unsigned(48, "0x800000000", {0, 8}),
  313. Make_Ok__Signed(48, "0x7fffffffffff", {0xffffffff, 0x7fff}),
  314. Make_Ok__Signed(48, "0x800000000000", {0, 0xffff8000}),
  315. Make_Bad_Signed(48, "0x1000000000000"),
  316. Make_Bad_Unsigned(48, "0x1000000000000"),
  317. // Check 64-bit numbers
  318. Make_Ok__Signed(64, "0x7fffffffffffffff", {0xffffffff, 0x7fffffff}),
  319. Make_Ok__Signed(64, "0x8000000000000000", {0x00000000, 0x80000000}),
  320. Make_Ok__Unsigned(64, "0x7fffffffffffffff", {0xffffffff, 0x7fffffff}),
  321. Make_Ok__Unsigned(64, "0x8000000000000000", {0x00000000, 0x80000000}),
  322. }));
  323. // clang-format on
  324. TEST(OverflowIntegerParse, Decimal) {
  325. std::string signed_input = "-18446744073709551616";
  326. std::string expected_message0 =
  327. "Invalid signed integer literal: " + signed_input;
  328. EXPECT_THAT(failedEncode(Make_Bad_Signed(64, signed_input.c_str()),
  329. IdTypeClass::kScalarIntegerType),
  330. Eq(expected_message0));
  331. std::string unsigned_input = "18446744073709551616";
  332. std::string expected_message1 =
  333. "Invalid unsigned integer literal: " + unsigned_input;
  334. EXPECT_THAT(failedEncode(Make_Bad_Unsigned(64, unsigned_input.c_str()),
  335. IdTypeClass::kScalarIntegerType),
  336. Eq(expected_message1));
  337. // TODO(dneto): When the given number doesn't have a leading sign,
  338. // we say we're trying to parse an unsigned number, even when the caller
  339. // asked for a signed number. This is kind of weird, but it's an
  340. // artefact of how we do the parsing.
  341. EXPECT_THAT(failedEncode(Make_Bad_Signed(64, unsigned_input.c_str()),
  342. IdTypeClass::kScalarIntegerType),
  343. Eq(expected_message1));
  344. }
  345. TEST(OverflowIntegerParse, Hex) {
  346. std::string input = "0x10000000000000000";
  347. std::string expected_message = "Invalid unsigned integer literal: " + input;
  348. EXPECT_THAT(failedEncode(Make_Bad_Signed(64, input.c_str()),
  349. IdTypeClass::kScalarIntegerType),
  350. Eq(expected_message));
  351. EXPECT_THAT(failedEncode(Make_Bad_Unsigned(64, input.c_str()),
  352. IdTypeClass::kScalarIntegerType),
  353. Eq(expected_message));
  354. }
  355. } // namespace
  356. } // namespace spvtools