writer/wgsl: Add paren around LHS of member accessors

When the LHS type is not one of the common expression types

Fixes operator precedence issues around pointers and member accesses.

Change-Id: I81b01c0c1050d087d5d68a93d15a66ee14b2fed6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51365
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton 2021-05-19 08:29:58 +00:00 committed by Commit Bot service account
parent ce8f868815
commit ee449e2625
2 changed files with 25 additions and 0 deletions

View File

@ -155,9 +155,20 @@ bool GeneratorImpl::EmitArrayAccessor(ast::ArrayAccessorExpression* expr) {
}
bool GeneratorImpl::EmitMemberAccessor(ast::MemberAccessorExpression* expr) {
bool paren_lhs =
!expr->structure()
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
ast::IdentifierExpression, ast::MemberAccessorExpression,
ast::TypeConstructorExpression>();
if (paren_lhs) {
out_ << "(";
}
if (!EmitExpression(expr->structure())) {
return false;
}
if (paren_lhs) {
out_ << ")";
}
out_ << ".";

View File

@ -34,6 +34,20 @@ TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
EXPECT_EQ(gen.result(), "str.mem");
}
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor_OfDref) {
auto* s = Structure("Data", {Member("mem", ty.f32())});
Global("str", s, ast::StorageClass::kPrivate);
auto* p = Const("p", nullptr, AddressOf("str"));
auto* expr = MemberAccessor(Deref("p"), "mem");
WrapInFunction(p, expr);
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
EXPECT_EQ(gen.result(), "(*(p)).mem");
}
} // namespace
} // namespace wgsl
} // namespace writer