tint: Fix ICE in ast::TemplatedIdentifier ctor

Invalid programs could attempt to construct an ast::TemplatedIdentifier with no template arguments.
In this situation an ast::Identifier should be constructed instead.

Bug: chromium:1417465
Change-Id: Id1516cd83679947b5346c69ce5453d72f4f93b49
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120841
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2023-02-21 22:01:48 +00:00 committed by Dawn LUCI CQ
parent 2f689a7efe
commit 60d3738102
3 changed files with 31 additions and 18 deletions

View File

@ -26,21 +26,25 @@ using TemplatedIdentifierTest = TestHelper;
TEST_F(TemplatedIdentifierTest, Creation) {
auto* i = Ident("ident", 1_a, Add("x", "y"), false, "x");
EXPECT_EQ(i->symbol, Symbols().Get("ident"));
ASSERT_EQ(i->arguments.Length(), 4u);
EXPECT_TRUE(i->arguments[0]->Is<ast::IntLiteralExpression>());
EXPECT_TRUE(i->arguments[1]->Is<ast::BinaryExpression>());
EXPECT_TRUE(i->arguments[2]->Is<ast::BoolLiteralExpression>());
EXPECT_TRUE(i->arguments[3]->Is<ast::IdentifierExpression>());
auto* t = i->As<TemplatedIdentifier>();
ASSERT_NE(t, nullptr);
ASSERT_EQ(t->arguments.Length(), 4u);
EXPECT_TRUE(t->arguments[0]->Is<IntLiteralExpression>());
EXPECT_TRUE(t->arguments[1]->Is<BinaryExpression>());
EXPECT_TRUE(t->arguments[2]->Is<BoolLiteralExpression>());
EXPECT_TRUE(t->arguments[3]->Is<IdentifierExpression>());
}
TEST_F(TemplatedIdentifierTest, Creation_WithSource) {
auto* i = Ident(Source{{20, 2}}, "ident", 1_a, Add("x", "y"), false, "x");
EXPECT_EQ(i->symbol, Symbols().Get("ident"));
ASSERT_EQ(i->arguments.Length(), 4u);
EXPECT_TRUE(i->arguments[0]->Is<ast::IntLiteralExpression>());
EXPECT_TRUE(i->arguments[1]->Is<ast::BinaryExpression>());
EXPECT_TRUE(i->arguments[2]->Is<ast::BoolLiteralExpression>());
EXPECT_TRUE(i->arguments[3]->Is<ast::IdentifierExpression>());
auto* t = i->As<TemplatedIdentifier>();
ASSERT_NE(t, nullptr);
ASSERT_EQ(t->arguments.Length(), 4u);
EXPECT_TRUE(t->arguments[0]->Is<IntLiteralExpression>());
EXPECT_TRUE(t->arguments[1]->Is<BinaryExpression>());
EXPECT_TRUE(t->arguments[2]->Is<BoolLiteralExpression>());
EXPECT_TRUE(t->arguments[3]->Is<IdentifierExpression>());
auto src = i->source;
EXPECT_EQ(src.range.begin.line, 20u);

View File

@ -1496,23 +1496,24 @@ class ProgramBuilder {
/// @param identifier the identifier symbol
/// @param args the templated identifier arguments
/// @return an ast::TemplatedIdentifier with the given symbol and template arguments
/// @return an ast::Identifier with the given symbol and template arguments
template <typename IDENTIFIER, typename... ARGS, typename = DisableIfSource<IDENTIFIER>>
const ast::TemplatedIdentifier* Ident(IDENTIFIER&& identifier, ARGS&&... args) {
const ast::Identifier* Ident(IDENTIFIER&& identifier, ARGS&&... args) {
return Ident(source_, std::forward<IDENTIFIER>(identifier), std::forward<ARGS>(args)...);
}
/// @param source the source information
/// @param identifier the identifier symbol
/// @param args the templated identifier arguments
/// @return an ast::TemplatedIdentifier with the given symbol and template arguments
/// @return an ast::Identifier with the given symbol and template arguments
template <typename IDENTIFIER, typename... ARGS>
const ast::TemplatedIdentifier* Ident(const Source& source,
IDENTIFIER&& identifier,
ARGS&&... args) {
const ast::Identifier* Ident(const Source& source, IDENTIFIER&& identifier, ARGS&&... args) {
auto arg_exprs = ExprList(std::forward<ARGS>(args)...);
if (arg_exprs.IsEmpty()) {
return create<ast::Identifier>(source, Sym(std::forward<IDENTIFIER>(identifier)));
}
return create<ast::TemplatedIdentifier>(source, Sym(std::forward<IDENTIFIER>(identifier)),
ExprList(std::forward<ARGS>(args)...),
utils::Empty);
std::move(arg_exprs), utils::Empty);
}
/// @param expr the expression

View File

@ -1111,5 +1111,13 @@ TEST_F(ParserImplErrorTest, InvalidUTF8) {
"fn fu\xD0nc() {}\n");
}
TEST_F(ParserImplErrorTest, Bug_Chromium_1417465) {
EXPECT("var<workgroup> vec4_data: array<mat4x4<f@32>, 256>;",
R"(test.wgsl:1:41 error: expected ',' for template argument list
var<workgroup> vec4_data: array<mat4x4<f@32>, 256>;
^
)");
}
} // namespace
} // namespace tint::reader::wgsl