Redeclaration of var over let/const/class should be a syntax error.
authorross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Dec 2018 22:14:20 +0000 (22:14 +0000)
committerross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Dec 2018 22:14:20 +0000 (22:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192298

Reviewed by Keith Miller.

JSTests:

* test262.yaml:
* test262/expectations.yaml:
Mark 46 tests as passing.

* stress/block-scope-redeclarations.js:
Add some new tests.

* stress/for-in-invalidate-context-weird-assignments.js:
* stress/for-in-tests.js:
Replace tests for outdated behavior with tests for SyntaxError.

* ChakraCore/test/LetConst/defer3.baseline-jsc:
* ChakraCore/test/LetConst/letvar.baseline-jsc:
Update expectations.

Source/JavaScriptCore:

From https://tc39.github.io/ecma262/#sec-block-static-semantics-early-errors:
It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the
VarDeclaredNames of StatementList.

Accordingly, this patch ensures that { let x; { var x; } } and { { var x; } let x; } are syntax errors.

For the "var after" scenario:
When checking for existing lexically-declared names, we can't simply check the current var scope;
we need to check *all* enclosing scopes up to (and including) the current var scope. In so doing,
we must also avoid violating the Annex B.3.5 condition that allows `try {} catch (e) { var e; }`.

For the "var before" scenario:
We ensure that lexical scopes always keep track of the vars being hoisted over them; this gives us
a simple way to check the current block's var-declared names prior to making a lexical declaration.

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseTryStatement):
* parser/Parser.h:
(JSC::Scope::Scope):
(JSC::Scope::setIsSimpleCatchParameterScope): Added.
(JSC::Scope::isSimpleCatchParameterScope): Added.
(JSC::Scope::declareVariable):
(JSC::Scope::addVariableBeingHoisted): Added.
(JSC::Scope::declareLexicalVariable):
(JSC::Scope::hasDeclaredVariable):
(JSC::Scope::hasLexicallyDeclaredVariable): Added.
(JSC::Parser::declareHoistedVariable): Added.
(JSC::Parser::declareVariable):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239354 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChakraCore/test/LetConst/defer3.baseline-jsc
JSTests/ChakraCore/test/LetConst/letvar.baseline-jsc
JSTests/ChangeLog
JSTests/stress/block-scope-redeclarations.js [new file with mode: 0644]
JSTests/stress/for-in-invalidate-context-weird-assignments.js
JSTests/stress/for-in-tests.js
JSTests/test262.yaml
JSTests/test262/expectations.yaml
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h

index 1a57ef2..4d35b46 100644 (file)
@@ -28,10 +28,10 @@ SyntaxError: Cannot declare a const variable twice: 'x'.
 SyntaxError: Cannot declare a let variable twice: 'x'.
 SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
 SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
-Syntax check succeeded
-Syntax check succeeded
-Syntax check succeeded
-Syntax check succeeded
+SyntaxError: Cannot declare a const variable twice: 'x'.
+SyntaxError: Cannot declare a let variable twice: 'x'.
+SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
+SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
 SyntaxError: Cannot declare a const variable twice: 'x'.
 SyntaxError: Cannot declare a let variable twice: 'x'.
 SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
index 90a3868..c22aceb 100644 (file)
@@ -1,8 +1,3 @@
 SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
-var x
-undefined
-let y
-var y
-undefined
-let x
-undefined
+SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'x'.
+SyntaxError: Cannot declare a let variable twice: 'x'.
index 772cffc..7dc3cf4 100644 (file)
@@ -1,3 +1,25 @@
+2018-12-18  Ross Kirsling  <ross.kirsling@sony.com>
+
+        Redeclaration of var over let/const/class should be a syntax error.
+        https://bugs.webkit.org/show_bug.cgi?id=192298
+
+        Reviewed by Keith Miller.
+
+        * test262.yaml:
+        * test262/expectations.yaml:
+        Mark 46 tests as passing.
+
+        * stress/block-scope-redeclarations.js:
+        Add some new tests.
+
+        * stress/for-in-invalidate-context-weird-assignments.js:
+        * stress/for-in-tests.js:
+        Replace tests for outdated behavior with tests for SyntaxError.
+
+        * ChakraCore/test/LetConst/defer3.baseline-jsc:
+        * ChakraCore/test/LetConst/letvar.baseline-jsc:
+        Update expectations.
+
 2018-12-18  Mark Lam  <mark.lam@apple.com>
 
         Skip the stress/elidable-new-object-roflcopter-then-exit.js test on 32-bit.
diff --git a/JSTests/stress/block-scope-redeclarations.js b/JSTests/stress/block-scope-redeclarations.js
new file mode 100644 (file)
index 0000000..e244647
--- /dev/null
@@ -0,0 +1,39 @@
+function shouldNotThrow(script) {
+  eval(script);
+}
+
+function shouldThrowSyntaxError(script) {
+    let error;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+
+    if (!(error instanceof SyntaxError))
+        throw new Error('Expected SyntaxError!');
+}
+
+shouldThrowSyntaxError('{ var x; let x; }');
+shouldThrowSyntaxError('{ { var x; } let x; }');
+shouldThrowSyntaxError('{ { { var x; } } let x; }');
+shouldThrowSyntaxError('{ let x; var x; }');
+shouldThrowSyntaxError('{ let x; { var x; } }');
+shouldThrowSyntaxError('{ let x; { { var x; } } }');
+
+shouldNotThrow('{ var x; { let x; } }');
+shouldNotThrow('{ var x; { { let x; } } }');
+shouldNotThrow('{ { let x; } var x; }');
+shouldNotThrow('{ { { let x; } } var x; }');
+
+shouldThrowSyntaxError('{ var x; const x = 0; }');
+shouldThrowSyntaxError('{ { var x; } const x = 0; }');
+shouldThrowSyntaxError('{ { { var x; } } const x = 0; }');
+shouldThrowSyntaxError('{ const x = 0; var x; }');
+shouldThrowSyntaxError('{ const x = 0; { var x; } }');
+shouldThrowSyntaxError('{ const x = 0; { { var x; } } }');
+
+shouldNotThrow('{ var x; { const x = 0; } }');
+shouldNotThrow('{ var x; { { const x = 0; } } }');
+shouldNotThrow('{ { const x = 0; } var x; }');
+shouldNotThrow('{ { { const x = 0; } } var x; }');
index d111a75..8c1a4fc 100644 (file)
@@ -9,20 +9,23 @@ function test(f) {
         f();
 }
 
-test(function() {
-    let o = {xx: 0};
-    for (let i in o) {
-        for (i in [0, 1, 2]) { }
-        assert(typeof i === "string");
-        assert(o[i] === undefined);
+function shouldThrowSyntaxError(script) {
+    let error;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
     }
-});
+
+    if (!(error instanceof SyntaxError))
+        throw new Error('Expected SyntaxError!');
+}
 
 test(function() {
     let o = {xx: 0};
     for (let i in o) {
-        for (var i of [0]) { }
-        assert(typeof i === "number");
+        for (i in [0, 1, 2]) { }
+        assert(typeof i === "string");
         assert(o[i] === undefined);
     }
 });
@@ -72,11 +75,20 @@ test(function() {
     }
 });
 
-test(function() {
-    let o = {xx: 0};
-    for (let i in o) {
-        var i = 0;
-        assert(typeof i === "number");
-        assert(o[i] === undefined);
-    }
-});
+shouldThrowSyntaxError(
+    `function f() {
+        let o = {xx: 0};
+        for (let i in o) {
+            for (var i of [0]) { }
+        }
+    }`
+);
+
+shouldThrowSyntaxError(
+    `function f() {
+        let o = {xx: 0};
+        for (let i in o) {
+            var i = 0;
+        }
+    }`
+);
index a685489..3282c5f 100644 (file)
@@ -1,3 +1,15 @@
+function shouldThrowSyntaxError(script) {
+    let error;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+
+    if (!(error instanceof SyntaxError))
+        throw new Error('Expected SyntaxError!');
+}
+
 (function() {
     // Iterate over an array with normal indexed properties.
     var foo = function() {
     }
 })();
 
-(function() {
-    var foo = function(a, b, first) {
-        {   
+shouldThrowSyntaxError(
+    `function foo(a, b) {
+        {
             let p = 'some-value';
             for (var p = b in a) {}
-            if (first)
-                return p;
         }
-        return p;
-    };
-    noInline(foo);
-    for (var i = 0; i < 10000; ++i) {
-        var expected = 'expected-result';
-        var result = foo({}, expected, true);
-        if (expected !== result)
-            throw new Error("bad result: " + result + "!==" + expected);
-    }
-    for (var i = 0; i < 10000; ++i) {
-        var expected = 'expected-result';
-        var result = foo({}, expected, false);
-        if (typeof result !== 'undefined')
-            throw new Error("bad result: " + result + "!== undefined");
-    }
-})();
+    }`
+);
 
 (function() {
     var foo = function(a, b, c) {
     }
 })();
 
-(function() {
-    var error = false;
-    try {
-        eval("(function() { 'use strict'; for (var i = 0 in {}) {}})()");
-    } catch(e) {
-        error = e instanceof SyntaxError;
-    }
-    if (!error)
-        throw new Error("Expected SyntaxError error");
-})();
+shouldThrowSyntaxError(
+    `function foo() {
+        'use strict';
+        for (var i = 0 in {}) {}
+    }`
+);
 
-(function() {
-    var error = false;
-    try {
-        eval("(function() { const i = 10; for (var i = 0 in {}) {}})()");
-    } catch(e) {
-        error = e instanceof SyntaxError;
-    }
-    if (!error)
-        throw new Error("Expected SyntaxError error");
-})();
+shouldThrowSyntaxError(
+    `function foo() {
+        const i = 10;
+        for (var i = 0 in {}) {}
+    }`
+);
index 22216fe..bcc7471 100644 (file)
 - path: test262/test/language/block-scope/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/async-generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/async-generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-class-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-class-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-const-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-const-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-function-declaration.js
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-generator-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-let-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-let-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-var-declaration.js
 - path: test262/test/language/statements/const/global-use-before-initialization-in-prior-statement.js
   cmd: runTest262 :normal, "ReferenceError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/const/redeclaration-error-from-within-strict-mode-function-const.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/const/syntax/block-scope-syntax-const-declarations-mixed-with-without-initialiser.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/const/syntax/block-scope-syntax-const-declarations-mixed-with-without-initialiser.js
 - path: test262/test/language/statements/for/head-const-fresh-binding-per-iteration.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for/head-let-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for/head-let-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for/head-let-destructuring.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for/head-let-destructuring.js
 - path: test262/test/language/statements/for-in/head-const-bound-names-fordecl-tdz.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/head-const-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-in/head-const-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/head-const-bound-names-let.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-in/head-const-fresh-binding-per-iteration.js
 - path: test262/test/language/statements/for-in/head-let-bound-names-fordecl-tdz.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/head-let-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-in/head-let-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-in/head-let-bound-names-let.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-in/head-let-destructuring.js
 - path: test262/test/language/statements/for-of/head-const-bound-names-fordecl-tdz.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-of/head-const-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-of/head-const-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-of/head-const-bound-names-let.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-of/head-const-fresh-binding-per-iteration.js
 - path: test262/test/language/statements/for-of/head-let-bound-names-fordecl-tdz.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-of/head-let-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-of/head-let-bound-names-in-stmt.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/for-of/head-let-bound-names-let.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/for-of/head-let-destructuring.js
 - path: test262/test/language/statements/let/global-use-before-initialization-in-prior-statement.js
   cmd: runTest262 :normal, "ReferenceError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/let/redeclaration-error-from-within-strict-mode-function.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/let/syntax/attempt-to-redeclare-let-binding-with-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/let/syntax/attempt-to-redeclare-let-binding-with-function-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/let/syntax/attempt-to-redeclare-let-binding-with-var.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/let/syntax/attempt-to-redeclare-let-binding-with-var.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/let/syntax/escaped-let.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/let/syntax/identifier-let-allowed-as-lefthandside-expression-strict.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/async-generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/async-generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+- path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration-nested-in-function.js
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+- path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration-nested-in-function.js
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-let-declaration.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-var-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-function-declaration.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-generator-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-class-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-class-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-const-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-const-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-function-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-function-declaration.js
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-generator-declaration.js
   cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-let-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-let-declaration.js
-  cmd: runTest262 :fail, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "SyntaxError", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-var-declaration.js
   cmd: runTest262 :normal, "NoException", ["../../../../../../harness/assert.js", "../../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-var-declaration.js
index ab63fc5..61b3182 100644 (file)
@@ -1765,25 +1765,18 @@ test/language/block-scope/syntax/redeclaration/async-function-declaration-attemp
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-var-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-var-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-var-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-class-declaration.js:
@@ -1794,12 +1787,8 @@ test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-r
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-let-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration-nested-in-function.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-class-declaration.js:
@@ -1814,34 +1803,21 @@ test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-var-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-var-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-class-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-const-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
 test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/block-scope/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-let-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/computed-property-names/class/static/method-number.js:
   default: "Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['1', '2', 'length', 'prototype', 'a', 'c', 'name'])` returns `true`"
   strict mode: "Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['1', '2', 'length', 'prototype', 'a', 'c', 'name'])` returns `true`"
@@ -3416,8 +3392,6 @@ test/language/statements/class/subclass/class-definition-superclass-generator.js
 test/language/statements/class/super-fielddefinition-initializer-abrupt-completion.js:
   default: "SyntaxError: Unexpected token '='. Expected an opening '(' before a method's parameter list."
   strict mode: "SyntaxError: Unexpected token '='. Expected an opening '(' before a method's parameter list."
-test/language/statements/const/redeclaration-error-from-within-strict-mode-function-const.js:
-  default: 'Test262: This statement should not be evaluated.'
 test/language/statements/do-while/let-array-with-newline.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-in/12.6.4-2.js:
@@ -3463,12 +3437,6 @@ test/language/statements/for-in/dstr-obj-prop-nested-obj-invalid.js:
 test/language/statements/for-in/dstr-obj-rest-not-last-element-invalid.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/for-in/head-const-bound-names-in-stmt.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/for-in/head-let-bound-names-in-stmt.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-in/head-lhs-cover-non-asnmt-trgt.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
@@ -3605,18 +3573,12 @@ test/language/statements/for-of/dstr-obj-prop-nested-obj-invalid.js:
 test/language/statements/for-of/dstr-obj-rest-not-last-element-invalid.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/for-of/head-const-bound-names-in-stmt.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-of/head-decl-no-expr.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-of/head-expr-no-expr.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/for-of/head-let-bound-names-in-stmt.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-of/head-lhs-cover-non-asnmt-trgt.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
@@ -3634,9 +3596,6 @@ test/language/statements/for-of/head-var-no-expr.js:
   strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-of/let-array-with-newline.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/statements/for/head-let-bound-names-in-stmt.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for/head-lhs-let.js:
   default: "SyntaxError: Unexpected token ';'. Expected a parameter pattern or a ')' in parameter list."
 test/language/statements/for/let-array-with-newline.js:
@@ -3700,13 +3659,8 @@ test/language/statements/labeled/value-yield-strict.js:
   strict mode: "SyntaxError: Cannot use 'yield' as a label in strict mode."
 test/language/statements/let/block-local-closure-set-before-initialization.js:
   default: 'Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all'
-test/language/statements/let/redeclaration-error-from-within-strict-mode-function.js:
-  default: 'Test262: This statement should not be evaluated.'
 test/language/statements/let/syntax/attempt-to-redeclare-let-binding-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/statements/let/syntax/attempt-to-redeclare-let-binding-with-var.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/let/syntax/escaped-let.js:
   default: "SyntaxError: Unexpected escaped characters in keyword token: 'l\\u0065t'"
 test/language/statements/switch/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-async-function-declaration.js:
@@ -3723,25 +3677,18 @@ test/language/statements/switch/syntax/redeclaration/async-function-declaration-
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/async-function-declaration-attempt-to-redeclare-with-var-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/statements/switch/syntax/redeclaration/class-declaration-attempt-to-redeclare-with-var-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/statements/switch/syntax/redeclaration/const-declaration-attempt-to-redeclare-with-var-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-class-declaration.js:
@@ -3754,7 +3701,6 @@ test/language/statements/switch/syntax/redeclaration/function-declaration-attemp
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/function-declaration-attempt-to-redeclare-with-var-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-class-declaration.js:
@@ -3769,34 +3715,21 @@ test/language/statements/switch/syntax/redeclaration/generator-declaration-attem
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/generator-declaration-attempt-to-redeclare-with-var-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
-test/language/statements/switch/syntax/redeclaration/let-declaration-attempt-to-redeclare-with-var-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-async-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-class-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-const-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-function-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-generator-declaration.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/switch/syntax/redeclaration/var-declaration-attempt-to-redeclare-with-let-declaration.js:
-  default: 'Test262: This statement should not be evaluated.'
-  strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/try/early-catch-function.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
index cd3138a..b9a8240 100644 (file)
@@ -1,3 +1,39 @@
+2018-12-18  Ross Kirsling  <ross.kirsling@sony.com>
+
+        Redeclaration of var over let/const/class should be a syntax error.
+        https://bugs.webkit.org/show_bug.cgi?id=192298
+
+        Reviewed by Keith Miller.
+
+        From https://tc39.github.io/ecma262/#sec-block-static-semantics-early-errors:
+        It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the
+        VarDeclaredNames of StatementList.
+
+        Accordingly, this patch ensures that { let x; { var x; } } and { { var x; } let x; } are syntax errors.
+
+        For the "var after" scenario:
+        When checking for existing lexically-declared names, we can't simply check the current var scope;
+        we need to check *all* enclosing scopes up to (and including) the current var scope. In so doing,
+        we must also avoid violating the Annex B.3.5 condition that allows `try {} catch (e) { var e; }`.
+
+        For the "var before" scenario:
+        We ensure that lexical scopes always keep track of the vars being hoisted over them; this gives us
+        a simple way to check the current block's var-declared names prior to making a lexical declaration.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseTryStatement):
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        (JSC::Scope::setIsSimpleCatchParameterScope): Added.
+        (JSC::Scope::isSimpleCatchParameterScope): Added.
+        (JSC::Scope::declareVariable):
+        (JSC::Scope::addVariableBeingHoisted): Added.
+        (JSC::Scope::declareLexicalVariable):
+        (JSC::Scope::hasDeclaredVariable):
+        (JSC::Scope::hasLexicallyDeclaredVariable): Added.
+        (JSC::Parser::declareHoistedVariable): Added.
+        (JSC::Parser::declareVariable):
+
 2018-12-18  David Kilzer  <ddkilzer@apple.com>
 
         clang-tidy: Use const reference for MediaTime parameter to prevent object copy
index 6832a58..6faedb5 100644 (file)
@@ -1759,6 +1759,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(
             catchScope->preventVarDeclarations();
             const Identifier* ident = nullptr;
             if (matchSpecIdentifier()) {
+                catchScope->setIsSimpleCatchParameterScope();
                 ident = m_token.m_data.ident;
                 catchPattern = context.createBindingLocation(m_token.m_location, *ident, m_token.m_startPosition, m_token.m_endPosition, AssignmentContext::DeclarationStatement);
                 next();
index 6533ef9..9cfc1c1 100644 (file)
@@ -173,6 +173,7 @@ public:
         , m_isAsyncFunctionBoundary(false)
         , m_isLexicalScope(false)
         , m_isGlobalCodeScope(false)
+        , m_isSimpleCatchParameterScope(false)
         , m_isFunctionBoundary(false)
         , m_isValidStrictMode(true)
         , m_hasArguments(false)
@@ -290,6 +291,9 @@ public:
     void setIsGlobalCodeScope() { m_isGlobalCodeScope = true; }
     bool isGlobalCodeScope() const { return m_isGlobalCodeScope; }
 
+    void setIsSimpleCatchParameterScope() { m_isSimpleCatchParameterScope = true; }
+    bool isSimpleCatchParameterScope() { return m_isSimpleCatchParameterScope; }
+
     void setIsLexicalScope() 
     { 
         m_isLexicalScope = true;
@@ -354,8 +358,6 @@ public:
         addResult.iterator->value.setIsVar();
         if (!isValidStrictMode)
             result |= DeclarationResult::InvalidStrictMode;
-        if (m_lexicalVariables.contains(ident->impl()))
-            result |= DeclarationResult::InvalidDuplicateDeclaration;
         return result;
     }
 
@@ -388,6 +390,12 @@ public:
         return result;
     }
 
+    void addVariableBeingHoisted(const Identifier* ident)
+    {
+        ASSERT(!m_allowsVarDeclarations);
+        m_variablesBeingHoisted.add(ident->impl());
+    }
+
     void addSloppyModeHoistableFunctionCandidate(const Identifier* ident)
     {
         ASSERT(m_allowsVarDeclarations);
@@ -421,7 +429,7 @@ public:
             addResult.iterator->value.setIsImportedNamespace();
         }
 
-        if (!addResult.isNewEntry)
+        if (!addResult.isNewEntry || m_variablesBeingHoisted.contains(ident->impl()))
             result |= DeclarationResult::InvalidDuplicateDeclaration;
         if (!isValidStrictMode)
             result |= DeclarationResult::InvalidStrictMode;
@@ -429,7 +437,7 @@ public:
         return result;
     }
 
-    bool hasDeclaredVariable(const Identifier& ident)
+    ALWAYS_INLINE bool hasDeclaredVariable(const Identifier& ident)
     {
         return hasDeclaredVariable(ident.impl());
     }
@@ -443,6 +451,11 @@ public:
         return entry.isVar(); // The callee isn't a "var".
     }
 
+    ALWAYS_INLINE bool hasLexicallyDeclaredVariable(const Identifier& ident)
+    {
+        return hasLexicallyDeclaredVariable(ident.impl());
+    }
+
     bool hasLexicallyDeclaredVariable(const RefPtr<UniquedStringImpl>& ident) const
     {
         return m_lexicalVariables.contains(ident.get());
@@ -798,6 +811,7 @@ private:
     bool m_isAsyncFunctionBoundary;
     bool m_isLexicalScope;
     bool m_isGlobalCodeScope;
+    bool m_isSimpleCatchParameterScope;
     bool m_isFunctionBoundary;
     bool m_isValidStrictMode;
     bool m_hasArguments;
@@ -816,6 +830,7 @@ private:
     VariableEnvironment m_declaredVariables;
     VariableEnvironment m_lexicalVariables;
     Vector<UniquedStringImplPtrSet, 6> m_usedVariables;
+    UniquedStringImplPtrSet m_variablesBeingHoisted;
     UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates;
     HashSet<UniquedStringImpl*> m_closedVariableCandidates;
     DeclarationStacks::FunctionStack m_functionDeclarations;
@@ -1208,11 +1223,31 @@ private:
         cleanupScope.setPopped();
         popScopeInternal(scope, shouldTrackClosedVariables);
     }
+
+    NEVER_INLINE DeclarationResultMask declareHoistedVariable(const Identifier* ident)
+    {
+        unsigned i = m_scopeStack.size() - 1;
+        ASSERT(i < m_scopeStack.size());
+        while (true) {
+            // Annex B.3.5 exempts `try {} catch (e) { var e; }` from being a syntax error.
+            // FIXME: This exemption should not apply if the var declaration is a for-of initializer.
+            if (m_scopeStack[i].hasLexicallyDeclaredVariable(*ident) && !m_scopeStack[i].isSimpleCatchParameterScope())
+                return DeclarationResult::InvalidDuplicateDeclaration;
+
+            if (m_scopeStack[i].allowsVarDeclarations())
+                return m_scopeStack[i].declareVariable(ident);
+
+            m_scopeStack[i].addVariableBeingHoisted(ident);
+
+            i--;
+            ASSERT(i < m_scopeStack.size());
+        }
+    }
     
     DeclarationResultMask declareVariable(const Identifier* ident, DeclarationType type = DeclarationType::VarDeclaration, DeclarationImportType importType = DeclarationImportType::NotImported)
     {
         if (type == DeclarationType::VarDeclaration)
-            return currentVariableScope()->declareVariable(ident);
+            return declareHoistedVariable(ident);
 
         ASSERT(type == DeclarationType::LetDeclaration || type == DeclarationType::ConstDeclaration);
         // Lexical variables declared at a top level scope that shadow arguments or vars are not allowed.