[parser] reject parenthesized patterns as DestructuringAssignmentTargets

http://tc39.github.io/ecma262/#sec-destructuring-assignment-static-semantics-early-errors
requires that DestructuringAssignmentTargets which do not match Pattern productions,
must return true for IsValidSimpleAssignmentTarget.

This change rejects parenthesized patterns with a SyntaxError.

BUG=v8:4662, v8:811
LOG=N
R=adamk@chromium.org, rossberg@chromium.org, nikolaos@chromium.org

Review URL: https://codereview.chromium.org/1585473002

Cr-Commit-Position: refs/heads/master@{#33254}
This commit is contained in:
caitpotter88 2016-01-12 16:40:25 -08:00 committed by Commit bot
parent cd646f88a1
commit 6b28f294c1
2 changed files with 58 additions and 2 deletions

View File

@ -3277,8 +3277,13 @@ void ParserBase<Traits>::CheckDestructuringElement(
MessageTemplate::kInvalidDestructuringTarget;
const Scanner::Location location(begin, end);
if (expression->IsArrayLiteral() || expression->IsObjectLiteral() ||
expression->IsAssignment())
expression->IsAssignment()) {
if (expression->is_parenthesized()) {
classifier->RecordPatternError(location, message);
}
return;
}
if (expression->IsProperty()) {
classifier->RecordBindingPatternError(location, message);
} else if (!this->IsAssignableIdentifier(expression)) {

View File

@ -6960,6 +6960,19 @@ TEST(DestructuringAssignmentPositiveTests) {
"{x: { y = 10 } }",
"[(({ x } = { x: 1 }) => x).a]",
// v8:4662
"{ x: (y) }",
"{ x: (y) = [] }",
"{ x: (foo.bar) }",
"{ x: (foo['bar']) }",
"[ ...(a) ]",
"[ ...(foo['bar']) ]",
"[ ...(foo.bar) ]",
"[ (y) ]",
"[ (foo.bar) ]",
"[ (foo['bar']) ]",
NULL};
// clang-format on
static const ParserFlag always_flags[] = {
@ -7066,6 +7079,23 @@ TEST(DestructuringAssignmentNegativeTests) {
"([a] = [])",
"(([a] = []))",
"(([a]) = [])",
// v8:4662
"{ x: ([y]) }",
"{ x: ([y] = []) }",
"{ x: ({y}) }",
"{ x: ({y} = {}) }",
"{ x: (++y) }",
"[ (...[a]) ]",
"[ ...([a]) ]",
"[ ...([a] = [])",
"[ ...[ ( [ a ] ) ] ]",
"[ ([a]) ]",
"[ (...[a]) ]",
"[ ([a] = []) ]",
"[ (++y) ]",
"[ ...(++y) ]",
NULL};
// clang-format on
static const ParserFlag always_flags[] = {
@ -7097,7 +7127,7 @@ TEST(DestructuringAssignmentNegativeTests) {
always_flags, arraysize(always_flags));
// Strict mode errors
const char* strict_context_data[][2] = {{"'use strict'; ", " = {}"},
const char* strict_context_data[][2] = {{"'use strict'; (", " = {})"},
{"'use strict'; for (", " of {}) {}"},
{"'use strict'; for (", " in {}) {}"},
{NULL, NULL}};
@ -7113,6 +7143,27 @@ TEST(DestructuringAssignmentNegativeTests) {
"[ arguments ]",
"[ eval = 0 ]",
"[ arguments = 0 ]",
// v8:4662
"{ x: (eval) }",
"{ x: (arguments) }",
"{ x: (eval = 0) }",
"{ x: (arguments = 0) }",
"{ x: (eval) = 0 }",
"{ x: (arguments) = 0 }",
"[ (eval) ]",
"[ (arguments) ]",
"[ (eval = 0) ]",
"[ (arguments = 0) ]",
"[ (eval) = 0 ]",
"[ (arguments) = 0 ]",
"[ ...(eval) ]",
"[ ...(arguments) ]",
"[ ...(eval = 0) ]",
"[ ...(arguments = 0) ]",
"[ ...(eval) = 0 ]",
"[ ...(arguments) = 0 ]",
NULL};
RunParserSyncTest(strict_context_data, strict_data, kError, NULL, 0,
always_flags, arraysize(always_flags));