tint: Add `i` suffix and validate UInt literal non-negative

In this patch, `i` suffix for SInt literal is added, making `-234i`
valid. Meanwhile, validation of UInt literal must not be negative is
add, making `-42u` invalid with proper error message.

Bugs: tint:1514, tint:1515
Change-Id: Idd0e9ae5649a62e7d348c29f95c2570049653bd8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88140
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
This commit is contained in:
Zhaoming Jiang 2022-04-27 10:48:12 +00:00 committed by Dawn LUCI CQ
parent 84ed048e5d
commit 3b1e30a496
2 changed files with 63 additions and 9 deletions

View File

@ -681,7 +681,13 @@ Token Lexer::build_token_from_int_if_possible(Source source,
size_t end,
int32_t base) {
auto res = strtoll(&at(start), nullptr, base);
if (matches(pos(), "u")) {
if (res < 0) {
return {Token::Type::kError, source,
"u32 (" + std::string{substr(start, end - start)} +
") must not be negative"};
}
if (static_cast<uint64_t>(res) >
static_cast<uint64_t>(std::numeric_limits<uint32_t>::max())) {
return {
@ -693,6 +699,10 @@ Token Lexer::build_token_from_int_if_possible(Source source,
return {source, static_cast<uint32_t>(res)};
}
if (matches(pos(), "i")) {
advance(1);
}
if (res < static_cast<int64_t>(std::numeric_limits<int32_t>::min())) {
return {Token::Type::kError, source,
"i32 (" + std::string{substr(start, end - start)} + ") too small"};

View File

@ -42,6 +42,29 @@ float MakeFloat(int sign, int biased_exponent, int mantissa) {
}
TEST_F(ParserImplTest, ConstLiteral_Int) {
{
auto p = parser("234");
auto c = p->const_literal();
EXPECT_TRUE(c.matched);
EXPECT_FALSE(c.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(c.value, nullptr);
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, 234);
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
}
{
auto p = parser("234i");
auto c = p->const_literal();
EXPECT_TRUE(c.matched);
EXPECT_FALSE(c.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(c.value, nullptr);
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, 234);
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
{
auto p = parser("-234");
auto c = p->const_literal();
EXPECT_TRUE(c.matched);
@ -52,6 +75,18 @@ TEST_F(ParserImplTest, ConstLiteral_Int) {
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, -234);
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
{
auto p = parser("-234i");
auto c = p->const_literal();
EXPECT_TRUE(c.matched);
EXPECT_FALSE(c.errored);
EXPECT_FALSE(p->has_error()) << p->error();
ASSERT_NE(c.value, nullptr);
ASSERT_TRUE(c->Is<ast::SintLiteralExpression>());
EXPECT_EQ(c->As<ast::SintLiteralExpression>()->value, -234);
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 6u}}));
}
}
TEST_F(ParserImplTest, ConstLiteral_Uint) {
auto p = parser("234u");
@ -65,6 +100,15 @@ TEST_F(ParserImplTest, ConstLiteral_Uint) {
EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
}
TEST_F(ParserImplTest, ConstLiteral_Uint_Negative) {
auto p = parser("-234u");
auto c = p->const_literal();
EXPECT_FALSE(c.matched);
EXPECT_TRUE(c.errored);
EXPECT_EQ(p->error(), "1:1: u32 (-234) must not be negative");
ASSERT_EQ(c.value, nullptr);
}
TEST_F(ParserImplTest, ConstLiteral_Float) {
auto p = parser("234.e12");
auto c = p->const_literal();