Commit 84a71a58 authored by Caitlin Potter's avatar Caitlin Potter Committed by Commit Bot

[parser] classify binding pattern errors when parsing await expression

await expressions are an invalid destructuring target, and should
result in a SyntaxError when used in a position where a destructuring
target is expected.

BUG=v8:7173
R=marja@chromium.org, adamk@chromium.org

Change-Id: I1bdb4bc13cb2e3e904fc4389a6e0abca1e0ed17f
Reviewed-on: https://chromium-review.googlesource.com/811946Reviewed-by: 's avatarSathya Gunasekaran (ooo until 12/12) <gsathya@chromium.org>
Commit-Queue: Caitlin Potter <caitp@igalia.com>
Cr-Commit-Position: refs/heads/master@{#49977}
parent ff3d8321
......@@ -3211,12 +3211,15 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
classifier()->RecordFormalParameterInitializerError(
scanner()->peek_location(),
MessageTemplate::kAwaitExpressionFormalParameter);
int await_pos = peek_position();
Consume(Token::AWAIT);
ExpressionT value = ParseUnaryExpression(CHECK_OK);
classifier()->RecordBindingPatternError(
Scanner::Location(await_pos, scanner()->location().end_pos),
MessageTemplate::kInvalidDestructuringTarget);
ExpressionT expr = factory()->NewAwait(value, await_pos);
impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
return expr;
......
......@@ -8570,6 +8570,64 @@ TEST(AsyncAwaitErrors) {
RunParserSyncTest(async_body_context_data, async_body_error_data, kError);
}
TEST(Regress7173) {
// Await expression is an invalid destructuring target, and should not crash
// clang-format off
const char* error_context_data[][2] = {
{ "'use strict'; async function f() {", "}" },
{ "async function f() {", "}" },
{ "'use strict'; function f() {", "}" },
{ "function f() {", "}" },
{ "let f = async() => {", "}" },
{ "let f = () => {", "}" },
{ "'use strict'; async function* f() {", "}" },
{ "async function* f() {", "}" },
{ "'use strict'; function* f() {", "}" },
{ "function* f() {", "}" },
{ nullptr, nullptr }
};
const char* error_data[] = {
"var [await f] = [];",
"let [await f] = [];",
"const [await f] = [];",
"var [...await f] = [];",
"let [...await f] = [];",
"const [...await f] = [];",
"var { await f } = {};",
"let { await f } = {};",
"const { await f } = {};",
"var { ...await f } = {};",
"let { ...await f } = {};",
"const { ...await f } = {};",
"var { f: await f } = {};",
"let { f: await f } = {};",
"const { f: await f } = {};"
"var { f: ...await f } = {};",
"let { f: ...await f } = {};",
"const { f: ...await f } = {};"
"var { [f]: await f } = {};",
"let { [f]: await f } = {};",
"const { [f]: await f } = {};",
"var { [f]: ...await f } = {};",
"let { [f]: ...await f } = {};",
"const { [f]: ...await f } = {};",
nullptr
};
// clang-format on
RunParserSyncTest(error_context_data, error_data, kError);
}
TEST(AsyncAwaitFormalParameters) {
// clang-format off
const char* context_for_formal_parameters[][2] = {
......
// Copyright 2017 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.
async function f() {
let [await b] = [];
return b;
}
f();
*%(basename)s:6: SyntaxError: Invalid destructuring assignment target
let [await b] = [];
^^^^^^^
SyntaxError: Invalid destructuring assignment target
// Copyright 2017 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.
async function f() {
let { a: await b } = { a: 1 };
return b;
}
f();
*%(basename)s:6: SyntaxError: Invalid destructuring assignment target
let { a: await b } = { a: 1 };
^^^^^^^
SyntaxError: Invalid destructuring assignment target
// Copyright 2017 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.
async function f() {
let { [await "a"]: a } = { a: 1 };
return a;
}
f();
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