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:
parent
2f689a7efe
commit
60d3738102
|
@ -26,21 +26,25 @@ using TemplatedIdentifierTest = TestHelper;
|
||||||
TEST_F(TemplatedIdentifierTest, Creation) {
|
TEST_F(TemplatedIdentifierTest, Creation) {
|
||||||
auto* i = Ident("ident", 1_a, Add("x", "y"), false, "x");
|
auto* i = Ident("ident", 1_a, Add("x", "y"), false, "x");
|
||||||
EXPECT_EQ(i->symbol, Symbols().Get("ident"));
|
EXPECT_EQ(i->symbol, Symbols().Get("ident"));
|
||||||
ASSERT_EQ(i->arguments.Length(), 4u);
|
auto* t = i->As<TemplatedIdentifier>();
|
||||||
EXPECT_TRUE(i->arguments[0]->Is<ast::IntLiteralExpression>());
|
ASSERT_NE(t, nullptr);
|
||||||
EXPECT_TRUE(i->arguments[1]->Is<ast::BinaryExpression>());
|
ASSERT_EQ(t->arguments.Length(), 4u);
|
||||||
EXPECT_TRUE(i->arguments[2]->Is<ast::BoolLiteralExpression>());
|
EXPECT_TRUE(t->arguments[0]->Is<IntLiteralExpression>());
|
||||||
EXPECT_TRUE(i->arguments[3]->Is<ast::IdentifierExpression>());
|
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) {
|
TEST_F(TemplatedIdentifierTest, Creation_WithSource) {
|
||||||
auto* i = Ident(Source{{20, 2}}, "ident", 1_a, Add("x", "y"), false, "x");
|
auto* i = Ident(Source{{20, 2}}, "ident", 1_a, Add("x", "y"), false, "x");
|
||||||
EXPECT_EQ(i->symbol, Symbols().Get("ident"));
|
EXPECT_EQ(i->symbol, Symbols().Get("ident"));
|
||||||
ASSERT_EQ(i->arguments.Length(), 4u);
|
auto* t = i->As<TemplatedIdentifier>();
|
||||||
EXPECT_TRUE(i->arguments[0]->Is<ast::IntLiteralExpression>());
|
ASSERT_NE(t, nullptr);
|
||||||
EXPECT_TRUE(i->arguments[1]->Is<ast::BinaryExpression>());
|
ASSERT_EQ(t->arguments.Length(), 4u);
|
||||||
EXPECT_TRUE(i->arguments[2]->Is<ast::BoolLiteralExpression>());
|
EXPECT_TRUE(t->arguments[0]->Is<IntLiteralExpression>());
|
||||||
EXPECT_TRUE(i->arguments[3]->Is<ast::IdentifierExpression>());
|
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;
|
auto src = i->source;
|
||||||
EXPECT_EQ(src.range.begin.line, 20u);
|
EXPECT_EQ(src.range.begin.line, 20u);
|
||||||
|
|
|
@ -1496,23 +1496,24 @@ class ProgramBuilder {
|
||||||
|
|
||||||
/// @param identifier the identifier symbol
|
/// @param identifier the identifier symbol
|
||||||
/// @param args the templated identifier arguments
|
/// @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>>
|
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)...);
|
return Ident(source_, std::forward<IDENTIFIER>(identifier), std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param identifier the identifier symbol
|
/// @param identifier the identifier symbol
|
||||||
/// @param args the templated identifier arguments
|
/// @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>
|
template <typename IDENTIFIER, typename... ARGS>
|
||||||
const ast::TemplatedIdentifier* Ident(const Source& source,
|
const ast::Identifier* Ident(const Source& source, IDENTIFIER&& identifier, ARGS&&... args) {
|
||||||
IDENTIFIER&& identifier,
|
auto arg_exprs = ExprList(std::forward<ARGS>(args)...);
|
||||||
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)),
|
return create<ast::TemplatedIdentifier>(source, Sym(std::forward<IDENTIFIER>(identifier)),
|
||||||
ExprList(std::forward<ARGS>(args)...),
|
std::move(arg_exprs), utils::Empty);
|
||||||
utils::Empty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param expr the expression
|
/// @param expr the expression
|
||||||
|
|
|
@ -1111,5 +1111,13 @@ TEST_F(ParserImplErrorTest, InvalidUTF8) {
|
||||||
"fn fu\xD0nc() {}\n");
|
"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
|
||||||
} // namespace tint::reader::wgsl
|
} // namespace tint::reader::wgsl
|
||||||
|
|
Loading…
Reference in New Issue