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>
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index a9607b2..45a77b8 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -155,9 +155,20 @@
}
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_ << ".";
diff --git a/src/writer/wgsl/generator_impl_member_accessor_test.cc b/src/writer/wgsl/generator_impl_member_accessor_test.cc
index 1a28011..03fccc6 100644
--- a/src/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -34,6 +34,20 @@
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