[parser] Fix parsing '#x in expr' in binary expressions

'#x in expr' currently parses incorrectly and associates #x as an
operand of an existing binary expression continuation if the previous
operator was of higher precedence. For example, 0 << #x in foo gets
incorrectly parsed as (0 << #x) in foo.

Bug: v8:12259, v8:12086
Change-Id: Ie37ff49ff6e63b3ea91fd0fba6bc73ec839c580b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3176506
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77020}
This commit is contained in:
Shu-yu Guo 2021-09-22 11:48:37 -07:00 committed by V8 LUCI CQ
parent 43bb214d65
commit 295f7133f6
3 changed files with 12 additions and 10 deletions

View File

@ -3233,20 +3233,21 @@ template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
int prec) {
DCHECK_GE(prec, 4);
ExpressionT x;
// "#foo in ShiftExpression" needs to be parsed separately, since private
// identifiers are not valid PrimaryExpressions.
if (V8_UNLIKELY(FLAG_harmony_private_brand_checks &&
peek() == Token::PRIVATE_NAME)) {
x = ParsePropertyOrPrivatePropertyName();
if (peek() != Token::IN) {
ReportUnexpectedToken(peek());
ExpressionT x = ParsePropertyOrPrivatePropertyName();
int prec1 = Token::Precedence(peek(), accept_IN_);
if (peek() != Token::IN || prec1 < prec) {
ReportUnexpectedToken(Token::PRIVATE_NAME);
return impl()->FailureExpression();
}
} else {
x = ParseUnaryExpression();
return ParseBinaryContinuation(x, prec, prec1);
}
ExpressionT x = ParseUnaryExpression();
int prec1 = Token::Precedence(peek(), accept_IN_);
if (prec1 >= prec) {
return ParseBinaryContinuation(x, prec, prec1);

View File

@ -565,3 +565,8 @@ const commonThrowCases = [100, 'foo', undefined, null];
assertFalse(d.exfilEval(c));
assertFalse(d.exfilEval(d));
})();
(function TestBinaryOperatorPrecedenceParseError() {
assertThrows(() => eval(`class C { #x; test() { 0 << #x in {} } }`),
SyntaxError);
})();

View File

@ -429,10 +429,6 @@
'built-ins/ShadowRealm/prototype/proto': [FAIL],
'built-ins/ShadowRealm/prototype/Symbol.toStringTag': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=12086
'language/expressions/in/private-field-invalid-assignment-reference': [FAIL],
'language/expressions/in/private-field-in-nested': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=12085
'language/statements/class/subclass/derived-class-return-override-catch-finally': [FAIL],
'language/statements/class/subclass/derived-class-return-override-catch-finally-arrow': [FAIL],