From 3b1e30a496e3b1e2ea92d37a84190fa0596f9948 Mon Sep 17 00:00:00 2001 From: Zhaoming Jiang Date: Wed, 27 Apr 2022 10:48:12 +0000 Subject: [PATCH] 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 Reviewed-by: Ben Clayton Commit-Queue: Zhaoming Jiang --- src/tint/reader/wgsl/lexer.cc | 10 +++ .../wgsl/parser_impl_const_literal_test.cc | 62 ++++++++++++++++--- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc index 122fcda93e..e7a3a4b782 100644 --- a/src/tint/reader/wgsl/lexer.cc +++ b/src/tint/reader/wgsl/lexer.cc @@ -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(res) > static_cast(std::numeric_limits::max())) { return { @@ -693,6 +699,10 @@ Token Lexer::build_token_from_int_if_possible(Source source, return {source, static_cast(res)}; } + if (matches(pos(), "i")) { + advance(1); + } + if (res < static_cast(std::numeric_limits::min())) { return {Token::Type::kError, source, "i32 (" + std::string{substr(start, end - start)} + ") too small"}; diff --git a/src/tint/reader/wgsl/parser_impl_const_literal_test.cc b/src/tint/reader/wgsl/parser_impl_const_literal_test.cc index 44c70832b4..e5cf61b668 100644 --- a/src/tint/reader/wgsl/parser_impl_const_literal_test.cc +++ b/src/tint/reader/wgsl/parser_impl_const_literal_test.cc @@ -42,15 +42,50 @@ 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()); - EXPECT_EQ(c->As()->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); + EXPECT_FALSE(c.errored); + EXPECT_FALSE(p->has_error()) << p->error(); + ASSERT_NE(c.value, nullptr); + ASSERT_TRUE(c->Is()); + EXPECT_EQ(c->As()->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()); + EXPECT_EQ(c->As()->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); + EXPECT_FALSE(c.errored); + EXPECT_FALSE(p->has_error()) << p->error(); + ASSERT_NE(c.value, nullptr); + ASSERT_TRUE(c->Is()); + EXPECT_EQ(c->As()->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()); + EXPECT_EQ(c->As()->value, -234); + EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 6u}})); + } } TEST_F(ParserImplTest, ConstLiteral_Uint) { @@ -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();