Commit 7e6bbab2 authored by mmaly@chromium.org's avatar mmaly@chromium.org

Strict mode delete of unqualified identifier.

SyntaxError is reported in strict mode when deleting
an unqualified identifier. (11.4.1 of Ecma-262 5th ed)

Review URL: http://codereview.chromium.org/6516003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6780 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6f2e90b1
...@@ -224,6 +224,7 @@ function FormatMessage(message) { ...@@ -224,6 +224,7 @@ function FormatMessage(message) {
strict_lhs_postfix: ["Postfix increment/decrement may not have eval or arguments operand in strict mode"], strict_lhs_postfix: ["Postfix increment/decrement may not have eval or arguments operand in strict mode"],
strict_lhs_prefix: ["Prefix increment/decrement may not have eval or arguments operand in strict mode"], strict_lhs_prefix: ["Prefix increment/decrement may not have eval or arguments operand in strict mode"],
strict_reserved_word: ["Use of future reserved word in strict mode"], strict_reserved_word: ["Use of future reserved word in strict mode"],
strict_delete: ["Delete of an unqualified identifier in strict mode."],
}; };
} }
var message_type = %MessageGetType(message); var message_type = %MessageGetType(message);
......
...@@ -2521,6 +2521,16 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { ...@@ -2521,6 +2521,16 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
} }
} }
// "delete identifier" is a syntax error in strict mode.
if (op == Token::DELETE && temp_scope_->StrictMode()) {
VariableProxy* operand = expression->AsVariableProxy();
if (operand != NULL && !operand->is_this()) {
ReportMessage("strict_delete", Vector<const char*>::empty());
*ok = false;
return NULL;
}
}
return new UnaryOperation(op, expression); return new UnaryOperation(op, expression);
} else if (Token::IsCountOp(op)) { } else if (Token::IsCountOp(op)) {
......
...@@ -359,16 +359,19 @@ chapter11/11.4/11.4.1/11.4.1-4.a-9-s: FAIL ...@@ -359,16 +359,19 @@ chapter11/11.4/11.4.1/11.4.1-4.a-9-s: FAIL
# delete operator throws ReferenceError when deleting a direct reference # delete operator throws ReferenceError when deleting a direct reference
# to a var in strict mode # to a var in strict mode
# Invalid test case. Test expects ReferenceError instead of SyntaxError.
# http://es5conform.codeplex.com/workitem/29084
chapter11/11.4/11.4.1/11.4.1-5-1-s: FAIL chapter11/11.4/11.4.1/11.4.1-5-1-s: FAIL
# delete operator throws ReferenceError when deleting a direct reference # delete operator throws ReferenceError when deleting a direct reference
# to a function argument in strict mode # to a function argument in strict mode
# Invalid test case. Test expects ReferenceError instead of SyntaxError.
# http://es5conform.codeplex.com/workitem/29084
chapter11/11.4/11.4.1/11.4.1-5-2-s: FAIL chapter11/11.4/11.4.1/11.4.1-5-2-s: FAIL
# delete operator throws ReferenceError when deleting a direct reference # delete operator throws ReferenceError when deleting a direct reference
# to a function name in strict mode # to a function name in strict mode
# Invalid test case. Test expects ReferenceError instead of SyntaxError.
# http://es5conform.codeplex.com/workitem/29084
chapter11/11.4/11.4.1/11.4.1-5-3-s: FAIL chapter11/11.4/11.4.1/11.4.1-5-3-s: FAIL
# delete operator throws SyntaxError when deleting a direct reference
# to a function argument(object) in strict mode
chapter11/11.4/11.4.1/11.4.1-5-4-s: FAIL
# eval - a function declaring a var named 'eval' throws EvalError in strict mode # eval - a function declaring a var named 'eval' throws EvalError in strict mode
# Invalid test case. SyntaxError should be expected instead of EvalError. # Invalid test case. SyntaxError should be expected instead of EvalError.
......
...@@ -169,13 +169,20 @@ CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError); ...@@ -169,13 +169,20 @@ CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError);
CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError); CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError);
CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError); CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError);
CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError); CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError);
CheckStrictMode("var x = { 123: 1, 123.00000000000000000000000000000000000000000000000000000000000000000001 : 2 }", SyntaxError); CheckStrictMode("var x = { \
123: 1, \
123.00000000000000000000000000000000000000000000000000000000000000000001: 2 \
}", SyntaxError);
// Non-conflicting data properties. // Non-conflicting data properties.
(function StrictModeNonDuplicate() { (function StrictModeNonDuplicate() {
"use strict"; "use strict";
var x = { 123 : 1, "0123" : 2 }; var x = { 123 : 1, "0123" : 2 };
var x = { 123: 1, '123.00000000000000000000000000000000000000000000000000000000000000000001' : 2 } var x = {
123: 1,
'123.00000000000000000000000000000000000000000000000000000000000000000001':
2
};
})(); })();
// Two getters (non-strict) // Two getters (non-strict)
...@@ -214,23 +221,32 @@ assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError); ...@@ -214,23 +221,32 @@ assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
CheckStrictMode("function strict() { eval = undefined; }", SyntaxError); CheckStrictMode("function strict() { eval = undefined; }", SyntaxError);
CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError); CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError);
CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError); CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError);
CheckStrictMode("function strict() { print(arguments = undefined); }", SyntaxError); CheckStrictMode("function strict() { print(arguments = undefined); }",
SyntaxError);
CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError); CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError);
CheckStrictMode("function strict() { var x = arguments = undefined; }", SyntaxError); CheckStrictMode("function strict() { var x = arguments = undefined; }",
SyntaxError);
// Compound assignment to eval or arguments // Compound assignment to eval or arguments
CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError); CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError);
CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError); CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError);
CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError); CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError);
CheckStrictMode("function strict() { print(arguments %= undefined); }", SyntaxError); CheckStrictMode("function strict() { print(arguments %= undefined); }",
CheckStrictMode("function strict() { var x = eval += undefined; }", SyntaxError); SyntaxError);
CheckStrictMode("function strict() { var x = arguments -= undefined; }", SyntaxError); CheckStrictMode("function strict() { var x = eval += undefined; }",
SyntaxError);
CheckStrictMode("function strict() { var x = arguments -= undefined; }",
SyntaxError);
CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError); CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError);
CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError); CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError);
CheckStrictMode("function strict() { print(eval >>>= undefined); }", SyntaxError); CheckStrictMode("function strict() { print(eval >>>= undefined); }",
CheckStrictMode("function strict() { print(arguments &= undefined); }", SyntaxError); SyntaxError);
CheckStrictMode("function strict() { var x = eval ^= undefined; }", SyntaxError); CheckStrictMode("function strict() { print(arguments &= undefined); }",
CheckStrictMode("function strict() { var x = arguments |= undefined; }", SyntaxError); SyntaxError);
CheckStrictMode("function strict() { var x = eval ^= undefined; }",
SyntaxError);
CheckStrictMode("function strict() { var x = arguments |= undefined; }",
SyntaxError);
// Postfix increment with eval or arguments // Postfix increment with eval or arguments
CheckStrictMode("function strict() { eval++; }", SyntaxError); CheckStrictMode("function strict() { eval++; }", SyntaxError);
...@@ -264,6 +280,17 @@ CheckStrictMode("function strict() { print(--arguments); }", SyntaxError); ...@@ -264,6 +280,17 @@ CheckStrictMode("function strict() { print(--arguments); }", SyntaxError);
CheckStrictMode("function strict() { var x = --eval; }", SyntaxError); CheckStrictMode("function strict() { var x = --eval; }", SyntaxError);
CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError); CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError);
// Delete of an unqialified identifier
CheckStrictMode("delete unqualified;", SyntaxError);
CheckStrictMode("function strict() { delete unqualified; }", SyntaxError);
CheckStrictMode("function function_name() { delete function_name; }",
SyntaxError);
CheckStrictMode("function strict(parameter) { delete parameter; }",
SyntaxError);
CheckStrictMode("function strict() { var variable; delete variable; }",
SyntaxError);
CheckStrictMode("var variable; delete variable;", SyntaxError);
// Prefix unary operators other than delete, ++, -- are valid in strict mode // Prefix unary operators other than delete, ++, -- are valid in strict mode
(function StrictModeUnaryOperators() { (function StrictModeUnaryOperators() {
"use strict"; "use strict";
...@@ -318,17 +345,22 @@ function testFutureReservedWord(word) { ...@@ -318,17 +345,22 @@ function testFutureReservedWord(word) {
// Function names and arguments when the body is strict // Function names and arguments when the body is strict
assertThrows("function " + word + " () { 'use strict'; }", SyntaxError); assertThrows("function " + word + " () { 'use strict'; }", SyntaxError);
assertThrows("function foo (" + word + ") 'use strict'; {}", SyntaxError); assertThrows("function foo (" + word + ") 'use strict'; {}", SyntaxError);
assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }", SyntaxError); assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }",
SyntaxError);
assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError); assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError);
assertThrows("function foo (" + word + ", a) { 'use strict'; }", SyntaxError); assertThrows("function foo (" + word + ", a) { 'use strict'; }", SyntaxError);
assertThrows("function foo (a, " + word + ", b) { 'use strict'; }", SyntaxError); assertThrows("function foo (a, " + word + ", b) { 'use strict'; }",
assertThrows("var foo = function (" + word + ") { 'use strict'; }", SyntaxError); SyntaxError);
assertThrows("var foo = function (" + word + ") { 'use strict'; }",
SyntaxError);
// get/set when the body is strict // get/set when the body is strict
eval("var x = { get " + word + " () { 'use strict'; } };"); eval("var x = { get " + word + " () { 'use strict'; } };");
eval("var x = { set " + word + " (value) { 'use strict'; } };"); eval("var x = { set " + word + " (value) { 'use strict'; } };");
assertThrows("var x = { get foo(" + word + ") { 'use strict'; } };", SyntaxError); assertThrows("var x = { get foo(" + word + ") { 'use strict'; } };",
assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };", SyntaxError); SyntaxError);
assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };",
SyntaxError);
} }
for (var i = 0; i < future_reserved_words.length; i++) { for (var i = 0; i < future_reserved_words.length; i++) {
......
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