[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:
parent
43bb214d65
commit
295f7133f6
@ -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);
|
||||
|
@ -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);
|
||||
})();
|
||||
|
@ -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],
|
||||
|
Loading…
Reference in New Issue
Block a user