Commit 6f290ef7 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Fix parsing "new super.x"

It's not "(new super).x" but "new (super.x)".

Bug: v8:11261
Change-Id: Ifc9cae038c1dc8fcdb096e213b4ac79ea20e9238
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2593248
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Auto-Submit: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71763}
parent c2e9357c
...@@ -1207,7 +1207,7 @@ class ParserBase { ...@@ -1207,7 +1207,7 @@ class ParserBase {
bool name_is_strict_reserved, bool name_is_strict_reserved,
int class_token_pos); int class_token_pos);
ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged); ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged);
ExpressionT ParseSuperExpression(bool is_new); ExpressionT ParseSuperExpression();
ExpressionT ParseImportExpressions(); ExpressionT ParseImportExpressions();
ExpressionT ParseNewTargetExpression(); ExpressionT ParseNewTargetExpression();
...@@ -1849,8 +1849,7 @@ ParserBase<Impl>::ParsePrimaryExpression() { ...@@ -1849,8 +1849,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
return ParseFunctionExpression(); return ParseFunctionExpression();
case Token::SUPER: { case Token::SUPER: {
const bool is_new = false; return ParseSuperExpression();
return ParseSuperExpression(is_new);
} }
case Token::IMPORT: case Token::IMPORT:
return ParseImportExpressions(); return ParseImportExpressions();
...@@ -3431,16 +3430,14 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() { ...@@ -3431,16 +3430,14 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
// new new foo means new (new foo) // new new foo means new (new foo)
// new new foo() means new (new foo()) // new new foo() means new (new foo())
// new new foo().bar().baz means (new (new foo()).bar()).baz // new new foo().bar().baz means (new (new foo()).bar()).baz
// new super.x means new (super.x)
Consume(Token::NEW); Consume(Token::NEW);
int new_pos = position(); int new_pos = position();
ExpressionT result; ExpressionT result;
CheckStackOverflow(); CheckStackOverflow();
if (peek() == Token::SUPER) { if (peek() == Token::IMPORT && PeekAhead() == Token::LPAREN) {
const bool is_new = true;
result = ParseSuperExpression(is_new);
} else if (peek() == Token::IMPORT && PeekAhead() == Token::LPAREN) {
impl()->ReportMessageAt(scanner()->peek_location(), impl()->ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kImportCallNotNewExpression); MessageTemplate::kImportCallNotNewExpression);
return impl()->FailureExpression(); return impl()->FailureExpression();
...@@ -3449,6 +3446,12 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() { ...@@ -3449,6 +3446,12 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
return ParseMemberExpressionContinuation(result); return ParseMemberExpressionContinuation(result);
} else { } else {
result = ParseMemberExpression(); result = ParseMemberExpression();
if (result->IsSuperCallReference()) {
// new super() is never allowed
impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kUnexpectedSuper);
return impl()->FailureExpression();
}
} }
if (peek() == Token::LPAREN) { if (peek() == Token::LPAREN) {
// NewExpression with arguments. // NewExpression with arguments.
...@@ -3576,8 +3579,8 @@ ParserBase<Impl>::ParseImportExpressions() { ...@@ -3576,8 +3579,8 @@ ParserBase<Impl>::ParseImportExpressions() {
} }
template <typename Impl> template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( typename ParserBase<Impl>::ExpressionT
bool is_new) { ParserBase<Impl>::ParseSuperExpression() {
Consume(Token::SUPER); Consume(Token::SUPER);
int pos = position(); int pos = position();
...@@ -3602,9 +3605,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( ...@@ -3602,9 +3605,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
UseThis(); UseThis();
return impl()->NewSuperPropertyReference(pos); return impl()->NewSuperPropertyReference(pos);
} }
// new super() is never allowed. // super() is only allowed in derived constructor. new super() is never
// super() is only allowed in derived constructor // allowed; it's reported as an error by
if (!is_new && peek() == Token::LPAREN && IsDerivedConstructor(kind)) { // ParseMemberWithPresentNewPrefixesExpression.
if (peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
// TODO(rossberg): This might not be the correct FunctionState for the // TODO(rossberg): This might not be the correct FunctionState for the
// method here. // method here.
expression_scope()->RecordThisUse(); expression_scope()->RecordThisUse();
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let obj = ({ __proto__: { x: class {} }, y() { return new super.x; } });
obj.y();
class A { static a = class {} }
class B extends A { static b() { return new super.a(); } }
B.b();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment