Commit 9b15445e authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

[parser] make kInvalidLhsInFor a SyntaxError

Second item in section 13.7.5.1 states that the error should be a
SyntaxError, when previously CheckAndRewriteReferenceExpression
would always emit a ReferenceError.

BUG=v8:4373
R=adamk, rossberg
LOG=N
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel

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

Cr-Commit-Position: refs/heads/master@{#30184}
parent 46d34252
...@@ -3693,7 +3693,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3693,7 +3693,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
if (!*ok) return nullptr; if (!*ok) return nullptr;
expression = this->CheckAndRewriteReferenceExpression( expression = this->CheckAndRewriteReferenceExpression(
expression, lhs_beg_pos, lhs_end_pos, expression, lhs_beg_pos, lhs_end_pos,
MessageTemplate::kInvalidLhsInFor, CHECK_OK); MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
ForEachStatement* loop = ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos); factory()->NewForEachStatement(mode, labels, stmt_pos);
......
...@@ -922,7 +922,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -922,7 +922,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
if (!*ok) return Statement::Default(); if (!*ok) return Statement::Default();
lhs = CheckAndRewriteReferenceExpression( lhs = CheckAndRewriteReferenceExpression(
lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
CHECK_OK); kSyntaxError, CHECK_OK);
ParseExpression(true, CHECK_OK); ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
ParseSubStatement(CHECK_OK); ParseSubStatement(CHECK_OK);
......
...@@ -714,6 +714,9 @@ class ParserBase : public Traits { ...@@ -714,6 +714,9 @@ class ParserBase : public Traits {
ExpressionT CheckAndRewriteReferenceExpression( ExpressionT CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos, ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok); MessageTemplate::Template message, bool* ok);
ExpressionT CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok);
// Used to validate property names in object literals and class literals // Used to validate property names in object literals and class literals
enum PropertyKind { enum PropertyKind {
...@@ -3937,6 +3940,16 @@ typename ParserBase<Traits>::ExpressionT ...@@ -3937,6 +3940,16 @@ typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression( ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos, ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok) { MessageTemplate::Template message, bool* ok) {
return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
message, kReferenceError, ok);
}
template <typename Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok) {
Scanner::Location location(beg_pos, end_pos); Scanner::Location location(beg_pos, end_pos);
if (this->IsIdentifier(expression)) { if (this->IsIdentifier(expression)) {
if (is_strict(language_mode()) && if (is_strict(language_mode()) &&
...@@ -3963,7 +3976,7 @@ ParserBase<Traits>::CheckAndRewriteReferenceExpression( ...@@ -3963,7 +3976,7 @@ ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT error = this->NewThrowReferenceError(message, pos); ExpressionT error = this->NewThrowReferenceError(message, pos);
return factory()->NewProperty(expression, error, pos); return factory()->NewProperty(expression, error, pos);
} else { } else {
this->ReportMessageAt(location, message, kReferenceError); this->ReportMessageAt(location, message, type);
*ok = false; *ok = false;
return this->EmptyExpression(); return this->EmptyExpression();
} }
......
*%(basename)s:9: ReferenceError: Invalid left-hand side in for-loop *%(basename)s:9: SyntaxError: Invalid left-hand side in for-loop
function f() { for ("unassignable" in {}); } function f() { for ("unassignable" in {}); }
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
ReferenceError: Invalid left-hand side in for-loop SyntaxError: Invalid left-hand side in for-loop
*%(basename)s:7: ReferenceError: Invalid left-hand side in for-loop *%(basename)s:7: SyntaxError: Invalid left-hand side in for-loop
function f() { for (new.target in {}); } function f() { for (new.target in {}); }
^^^^^^^^^^ ^^^^^^^^^^
ReferenceError: Invalid left-hand side in for-loop SyntaxError: Invalid left-hand side in for-loop
...@@ -394,5 +394,5 @@ ...@@ -394,5 +394,5 @@
assertThrows(function() { Function("--new.target"); }, ReferenceError); assertThrows(function() { Function("--new.target"); }, ReferenceError);
assertThrows(function() { Function("(new.target)++"); }, ReferenceError); assertThrows(function() { Function("(new.target)++"); }, ReferenceError);
assertThrows(function() { Function("++(new.target)"); }, ReferenceError); assertThrows(function() { Function("++(new.target)"); }, ReferenceError);
assertThrows(function() { Function("for (new.target of {});"); }, ReferenceError); assertThrows(function() { Function("for (new.target of {});"); }, SyntaxError);
})(); })();
...@@ -50,9 +50,9 @@ assertDoesNotThrow("if (false) ++(eval('12'))", ReferenceError); ...@@ -50,9 +50,9 @@ assertDoesNotThrow("if (false) ++(eval('12'))", ReferenceError);
assertDoesNotThrow("if (false) (eval('12'))++", ReferenceError); assertDoesNotThrow("if (false) (eval('12'))++", ReferenceError);
// For in: // For in:
assertThrows("for (12 in [1]) print(12);", ReferenceError); assertThrows("for (12 in [1]) print(12);", SyntaxError);
assertThrows("for (eval('var x') in [1]) print(12);", ReferenceError); assertThrows("for (eval('var x') in [1]) print(12);", ReferenceError);
assertThrows("if (false) for (12 in [1]) print(12);", ReferenceError); assertThrows("if (false) for (12 in [1]) print(12);", SyntaxError);
assertDoesNotThrow("if (false) for (eval('0') in [1]) print(12);", ReferenceError); assertDoesNotThrow("if (false) for (eval('0') in [1]) print(12);", ReferenceError);
// For: // For:
...@@ -64,7 +64,7 @@ assertDoesNotThrow("if (false) for (eval('var x') = 1;;) print(12);", ReferenceE ...@@ -64,7 +64,7 @@ assertDoesNotThrow("if (false) for (eval('var x') = 1;;) print(12);", ReferenceE
// Assignments to 'this'. // Assignments to 'this'.
assertThrows("this = 42", ReferenceError); assertThrows("this = 42", ReferenceError);
assertThrows("function f() { this = 12; }", ReferenceError); assertThrows("function f() { this = 12; }", ReferenceError);
assertThrows("for (this in {x:3, y:4, z:5}) ;", ReferenceError); assertThrows("for (this in {x:3, y:4, z:5}) ;", SyntaxError);
assertThrows("for (this = 0;;) ;", ReferenceError); assertThrows("for (this = 0;;) ;", ReferenceError);
assertThrows("this++", ReferenceError); assertThrows("this++", ReferenceError);
assertThrows("++this", ReferenceError); assertThrows("++this", ReferenceError);
......
...@@ -422,36 +422,36 @@ PASS Valid: "for (a() in b) break" ...@@ -422,36 +422,36 @@ PASS Valid: "for (a() in b) break"
PASS Valid: "function f() { for (a() in b) break }" PASS Valid: "function f() { for (a() in b) break }"
PASS Valid: "for (a().l[4] in b) break" PASS Valid: "for (a().l[4] in b) break"
PASS Valid: "function f() { for (a().l[4] in b) break }" PASS Valid: "function f() { for (a().l[4] in b) break }"
PASS Valid: "for (new a in b in c in d) break" PASS Invalid: "for (new a in b in c in d) break"
PASS Valid: "function f() { for (new a in b in c in d) break }" PASS Invalid: "function f() { for (new a in b in c in d) break }"
PASS Valid: "for (new new new a in b) break" PASS Invalid: "for (new new new a in b) break"
PASS Valid: "function f() { for (new new new a in b) break }" PASS Invalid: "function f() { for (new new new a in b) break }"
FAIL Invalid: "for (delete new a() in b) break" should throw undefined PASS Invalid: "for (delete new a() in b) break"
FAIL Invalid: "function f() { for (delete new a() in b) break }" should throw undefined PASS Invalid: "function f() { for (delete new a() in b) break }"
FAIL Invalid: "for (a * a in b) break" should throw undefined PASS Invalid: "for (a * a in b) break"
FAIL Invalid: "function f() { for (a * a in b) break }" should throw undefined PASS Invalid: "function f() { for (a * a in b) break }"
PASS Valid: "for ((a * a) in b) break" PASS Invalid: "for ((a * a) in b) break"
PASS Valid: "function f() { for ((a * a) in b) break }" PASS Invalid: "function f() { for ((a * a) in b) break }"
FAIL Invalid: "for (a++ in b) break" should throw undefined PASS Invalid: "for (a++ in b) break"
FAIL Invalid: "function f() { for (a++ in b) break }" should throw undefined PASS Invalid: "function f() { for (a++ in b) break }"
PASS Valid: "for ((a++) in b) break" PASS Invalid: "for ((a++) in b) break"
PASS Valid: "function f() { for ((a++) in b) break }" PASS Invalid: "function f() { for ((a++) in b) break }"
FAIL Invalid: "for (++a in b) break" should throw undefined PASS Invalid: "for (++a in b) break"
FAIL Invalid: "function f() { for (++a in b) break }" should throw undefined PASS Invalid: "function f() { for (++a in b) break }"
PASS Valid: "for ((++a) in b) break" PASS Invalid: "for ((++a) in b) break"
PASS Valid: "function f() { for ((++a) in b) break }" PASS Invalid: "function f() { for ((++a) in b) break }"
FAIL Invalid: "for (a, b in c) break" should throw undefined PASS Invalid: "for (a, b in c) break"
FAIL Invalid: "function f() { for (a, b in c) break }" should throw undefined PASS Invalid: "function f() { for (a, b in c) break }"
FAIL Invalid: "for (a,b in c ;;) break" should throw undefined PASS Invalid: "for (a,b in c ;;) break"
FAIL Invalid: "function f() { for (a,b in c ;;) break }" should throw undefined PASS Invalid: "function f() { for (a,b in c ;;) break }"
PASS Valid: "for (a,(b in c) ;;) break" PASS Valid: "for (a,(b in c) ;;) break"
PASS Valid: "function f() { for (a,(b in c) ;;) break }" PASS Valid: "function f() { for (a,(b in c) ;;) break }"
PASS Valid: "for ((a, b) in c) break" PASS Invalid: "for ((a, b) in c) break"
PASS Valid: "function f() { for ((a, b) in c) break }" PASS Invalid: "function f() { for ((a, b) in c) break }"
FAIL Invalid: "for (a ? b : c in c) break" should throw undefined PASS Invalid: "for (a ? b : c in c) break"
FAIL Invalid: "function f() { for (a ? b : c in c) break }" should throw undefined PASS Invalid: "function f() { for (a ? b : c in c) break }"
PASS Valid: "for ((a ? b : c) in c) break" PASS Invalid: "for ((a ? b : c) in c) break"
PASS Valid: "function f() { for ((a ? b : c) in c) break }" PASS Invalid: "function f() { for ((a ? b : c) in c) break }"
PASS Valid: "for (var a in b in c) break" PASS Valid: "for (var a in b in c) break"
PASS Valid: "function f() { for (var a in b in c) break }" PASS Valid: "function f() { for (var a in b in c) break }"
PASS Valid: "for (var a = 5 += 6 in b) break" PASS Valid: "for (var a = 5 += 6 in b) break"
......
...@@ -291,21 +291,21 @@ invalid("for ( %a ; ; ) { }"); ...@@ -291,21 +291,21 @@ invalid("for ( %a ; ; ) { }");
valid ("for (a in b) break"); valid ("for (a in b) break");
valid ("for (a() in b) break"); valid ("for (a() in b) break");
valid ("for (a().l[4] in b) break"); valid ("for (a().l[4] in b) break");
valid ("for (new a in b in c in d) break"); invalid("for (new a in b in c in d) break");
valid ("for (new new new a in b) break"); invalid("for (new new new a in b) break");
invalid("for (delete new a() in b) break"); invalid("for (delete new a() in b) break");
invalid("for (a * a in b) break"); invalid("for (a * a in b) break");
valid ("for ((a * a) in b) break"); invalid("for ((a * a) in b) break");
invalid("for (a++ in b) break"); invalid("for (a++ in b) break");
valid ("for ((a++) in b) break"); invalid("for ((a++) in b) break");
invalid("for (++a in b) break"); invalid("for (++a in b) break");
valid ("for ((++a) in b) break"); invalid("for ((++a) in b) break");
invalid("for (a, b in c) break"); invalid("for (a, b in c) break");
invalid("for (a,b in c ;;) break"); invalid("for (a,b in c ;;) break");
valid ("for (a,(b in c) ;;) break"); valid ("for (a,(b in c) ;;) break");
valid ("for ((a, b) in c) break"); invalid("for ((a, b) in c) break");
invalid("for (a ? b : c in c) break"); invalid("for (a ? b : c in c) break");
valid ("for ((a ? b : c) in c) break"); invalid("for ((a ? b : c) in c) break");
valid ("for (var a in b in c) break"); valid ("for (var a in b in c) break");
valid ("for (var a = 5 += 6 in b) break"); valid ("for (var a = 5 += 6 in b) break");
invalid("for (var a += 5 in b) break"); invalid("for (var a += 5 in b) break");
......
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