writer/msl: Add parentheses for member accesses

The LHS should be wrapped in parentheses if it has lower precedence
than the access. This fixes issues with pointer dereferences followed
by member accesses, where we were previously generating *a.b.

Fixed: tint:831
Change-Id: I8a194ad4f54c80a01c24eb983ec8064037575216
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51963
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
James Price 2021-05-27 14:15:47 +00:00 committed by Tint LUCI CQ
parent 42d89ca199
commit 5102f87e38
5 changed files with 56 additions and 4 deletions

View File

@ -1728,9 +1728,20 @@ bool GeneratorImpl::EmitIf(ast::IfStatement* stmt) {
}
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

@ -1 +1 @@
SKIP: crbug.com/tint/831
SKIP: crbug.com/tint/833 loop emission is broken

View File

@ -1 +1,16 @@
SKIP: crbug.com/tint/831
#include <metal_stdlib>
using namespace metal;
struct S {
int i;
};
kernel void tint_symbol() {
thread S tint_symbol_2 = {};
thread S* const tint_symbol_1 = &(tint_symbol_2);
int i = 0;
int const x_15 = (*(tint_symbol_1)).i;
i = x_15;
return;
}

View File

@ -1 +1,14 @@
SKIP: crbug.com/tint/831
#include <metal_stdlib>
using namespace metal;
struct S {
int i;
};
kernel void tint_symbol() {
thread S tint_symbol_2 = {};
thread S* const tint_symbol_1 = &(tint_symbol_2);
int const i = (*(tint_symbol_1)).i;
return;
}

View File

@ -1 +1,14 @@
SKIP: crbug.com/tint/831
#include <metal_stdlib>
using namespace metal;
struct S {
int i;
};
kernel void tint_symbol() {
thread S tint_symbol_2 = {};
thread S* const tint_symbol_1 = &(tint_symbol_2);
(*(tint_symbol_1)).i = 5;
return;
}