writer: Add parentheses for array accesses
The LHS should be wrapped in parentheses if it has lower precedence than the access. This fixes issues with pointer dereferences followed by array accesses, where we were previously generating *a[i]. Change-Id: I639f94b642f32119350b0a0d23f4ff2a5d6c3c25 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/52843 Auto-Submit: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
42220ba1b2
commit
b487c71e59
|
@ -70,7 +70,7 @@ fn f() {
|
|||
auto* expect = R"(
|
||||
fn f() {
|
||||
var m : mat4x4<f32>;
|
||||
let f : f32 = *(&(*(&(*(&(m))[2]))[1]));
|
||||
let f : f32 = *(&((*(&((*(&(m)))[2])))[1]));
|
||||
}
|
||||
)";
|
||||
|
||||
|
@ -220,7 +220,7 @@ fn f() {
|
|||
let j : i32 = 1;
|
||||
let p_save = i;
|
||||
let q_save = j;
|
||||
*(&(*(&(arr[p_save]))[q_save])) = 12;
|
||||
*(&((*(&(arr[p_save])))[q_save])) = 12;
|
||||
}
|
||||
)";
|
||||
|
||||
|
|
|
@ -165,9 +165,20 @@ bool GeneratorImpl::EmitConstructedType(const sem::Type* ty) {
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitArrayAccessor(ast::ArrayAccessorExpression* expr) {
|
||||
bool paren_lhs =
|
||||
!expr->array()
|
||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||
ast::TypeConstructorExpression>();
|
||||
if (paren_lhs) {
|
||||
out_ << "(";
|
||||
}
|
||||
if (!EmitExpression(expr->array())) {
|
||||
return false;
|
||||
}
|
||||
if (paren_lhs) {
|
||||
out_ << ")";
|
||||
}
|
||||
out_ << "[";
|
||||
|
||||
if (!EmitExpression(expr->idx_expr())) {
|
||||
|
|
|
@ -32,6 +32,19 @@ TEST_F(MslGeneratorImplTest, ArrayAccessor) {
|
|||
EXPECT_EQ(gen.result(), "ary[5]");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, ArrayAccessor_OfDref) {
|
||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* p = Const("p", nullptr, AddressOf("ary"));
|
||||
auto* expr = IndexAccessor(Deref("p"), 5);
|
||||
WrapInFunction(p, expr);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), "(*(p))[5]");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace msl
|
||||
} // namespace writer
|
||||
|
|
|
@ -141,9 +141,20 @@ bool GeneratorImpl::EmitExpression(ast::Expression* expr) {
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitArrayAccessor(ast::ArrayAccessorExpression* expr) {
|
||||
bool paren_lhs =
|
||||
!expr->array()
|
||||
->IsAnyOf<ast::ArrayAccessorExpression, ast::CallExpression,
|
||||
ast::IdentifierExpression, ast::MemberAccessorExpression,
|
||||
ast::TypeConstructorExpression>();
|
||||
if (paren_lhs) {
|
||||
out_ << "(";
|
||||
}
|
||||
if (!EmitExpression(expr->array())) {
|
||||
return false;
|
||||
}
|
||||
if (paren_lhs) {
|
||||
out_ << ")";
|
||||
}
|
||||
out_ << "[";
|
||||
|
||||
if (!EmitExpression(expr->idx_expr())) {
|
||||
|
|
|
@ -32,6 +32,19 @@ TEST_F(WgslGeneratorImplTest, ArrayAccessor) {
|
|||
EXPECT_EQ(gen.result(), "ary[5]");
|
||||
}
|
||||
|
||||
TEST_F(WgslGeneratorImplTest, ArrayAccessor_OfDref) {
|
||||
Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* p = Const("p", nullptr, AddressOf("ary"));
|
||||
auto* expr = IndexAccessor(Deref("p"), 5);
|
||||
WrapInFunction(p, expr);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
|
||||
EXPECT_EQ(gen.result(), "(*(p))[5]");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace wgsl
|
||||
} // namespace writer
|
||||
|
|
Loading…
Reference in New Issue