From 38329a703831e2bd12b92b1f175991904c99b34c Mon Sep 17 00:00:00 2001
From: jugglinmike <mike@mikepennisi.com>
Date: Thu, 21 Apr 2016 15:54:25 -0400
Subject: [PATCH] Add tests for TryStatement binding restrictions (#577)

This changeset includes tests for early errors and those generated
dynamically by eval. It also accounts for relevant AnnexB extensions.
---
 .../var-env-lower-lex-catch-non-strict.js     | 32 +++++++++++++++++++
 .../try/catch-redeclared-for-in-var.js        | 28 ++++++++++++++++
 .../try/catch-redeclared-for-var.js           | 28 ++++++++++++++++
 .../var-env-lower-lex-catch-non-strict.js     | 21 ++++++++++++
 .../statements/try/early-catch-duplicates.js  | 14 ++++++++
 .../statements/try/early-catch-lex.js         | 15 +++++++++
 .../statements/try/early-catch-var.js         | 19 +++++++++++
 7 files changed, 157 insertions(+)
 create mode 100644 test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
 create mode 100644 test/annexB/language/statements/try/catch-redeclared-for-in-var.js
 create mode 100644 test/annexB/language/statements/try/catch-redeclared-for-var.js
 create mode 100644 test/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
 create mode 100644 test/language/statements/try/early-catch-duplicates.js
 create mode 100644 test/language/statements/try/early-catch-lex.js
 create mode 100644 test/language/statements/try/early-catch-var.js

diff --git a/test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js b/test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
new file mode 100644
index 0000000000..a9e16da021
--- /dev/null
+++ b/test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-variablestatements-in-catch-blocks
+es6id: B3.5
+description: Re-declaration of catch parameter
+info: >
+    [...]
+
+    This modified behaviour also applies to var and function declarations
+    introduced by direct evals contained within the Block of a Catch clause.
+    This change is accomplished by modify the algorithm of 18.2.1.2 as follows:
+
+    Step 5.d.ii.2.a.i is replaced by:
+
+    i. If thisEnvRec is not the Environment Record for a Catch clause, throw a
+       SyntaxError exception.
+    ii. If name is bound by any syntactic form other than a
+        FunctionDeclaration, a VariableStatement, the VariableDeclarationList
+        of a for statement, or the ForBinding of a for-in statement, throw a
+        SyntaxError exception.
+flags: [noStrict]
+---*/
+
+try {
+  throw null;
+} catch (err) {
+  eval('function err() {}');
+  eval('var err;');
+  eval('for (var err; false; ) {}');
+  eval('for (var err in []) {}');
+}
diff --git a/test/annexB/language/statements/try/catch-redeclared-for-in-var.js b/test/annexB/language/statements/try/catch-redeclared-for-in-var.js
new file mode 100644
index 0000000000..9c13d145b4
--- /dev/null
+++ b/test/annexB/language/statements/try/catch-redeclared-for-in-var.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-variablestatements-in-catch-blocks
+es6id: B3.5
+description: Re-declaration of catch parameter (for-in statement)
+info: >
+    It is a Syntax Error if any element of the BoundNames of CatchParameter
+    also occurs in the VarDeclaredNames of Block, unless that element is only
+    bound by a VariableStatement or the VariableDeclarationList of a for
+    statement, or the ForBinding of a for-in statement.
+---*/
+
+var before, during, after;
+
+try {
+  throw 'exception';
+} catch (err) {
+  before = err;
+  for (var err in { propertyName: null }) {
+    during = err;
+  }
+  after = err;
+}
+
+assert.sameValue(before, 'exception');
+assert.sameValue(during, 'propertyName', 'during loop body evaluation');
+assert.sameValue(after, 'propertyName', 'after loop body evaluation');
diff --git a/test/annexB/language/statements/try/catch-redeclared-for-var.js b/test/annexB/language/statements/try/catch-redeclared-for-var.js
new file mode 100644
index 0000000000..68b7e40041
--- /dev/null
+++ b/test/annexB/language/statements/try/catch-redeclared-for-var.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-variablestatements-in-catch-blocks
+es6id: B3.5
+description: Re-declaration of catch parameter (for-in statement)
+info: >
+    It is a Syntax Error if any element of the BoundNames of CatchParameter
+    also occurs in the VarDeclaredNames of Block, unless that element is only
+    bound by a VariableStatement or the VariableDeclarationList of a for
+    statement, or the ForBinding of a for-in statement.
+---*/
+
+var before, during, after;
+
+try {
+  throw 'exception';
+} catch (err) {
+  before = err;
+  for (var err = 'loop initializer'; err !== 'increment'; err = 'increment') {
+    during = err;
+  }
+  after = err;
+}
+
+assert.sameValue(before, 'exception');
+assert.sameValue(during, 'loop initializer');
+assert.sameValue(after, 'increment');
diff --git a/test/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js b/test/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
new file mode 100644
index 0000000000..bccdbe5024
--- /dev/null
+++ b/test/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-evaldeclarationinstantiation
+es6id: 18.2.1.2
+description: Variable collision with lexical binding in lower scope
+info: >
+    Annex B extensions permit re-declarations from FunctionDeclaration,
+    VariableStatement, the VariableDeclarationList of a for statement, and the
+    ForBinding of a for-in statement. Bindings from the ForBinding of a for-of
+    statement are restricted regardless of the application of Annex B.
+flags: [noStrict]
+---*/
+
+assert.throws(SyntaxError, function() {
+  try {
+    throw null;
+  } catch (err) {
+    eval('for (var err of []) {}');
+  }
+});
diff --git a/test/language/statements/try/early-catch-duplicates.js b/test/language/statements/try/early-catch-duplicates.js
new file mode 100644
index 0000000000..59fedeeafd
--- /dev/null
+++ b/test/language/statements/try/early-catch-duplicates.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-try-statement-static-semantics-early-errors
+es6id: 13.15.1
+description: >
+    It is a Syntax Error if BoundNames of CatchParameter contains any duplicate
+    elements.
+negative: SyntaxError
+---*/
+
+$ERROR('This code should not be executed.');
+
+try { } catch ([x, x]) {}
diff --git a/test/language/statements/try/early-catch-lex.js b/test/language/statements/try/early-catch-lex.js
new file mode 100644
index 0000000000..e685e3369b
--- /dev/null
+++ b/test/language/statements/try/early-catch-lex.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-try-statement-static-semantics-early-errors
+es6id: 13.15.1
+description: >
+    It is a Syntax Error if any element of the BoundNames of CatchParameter
+    also occurs in the LexicallyDeclaredNames of Block.
+negative: SyntaxError
+features: [let]
+---*/
+
+$ERROR('This code should not be executed.');
+
+try { } catch (x) { let x; }
diff --git a/test/language/statements/try/early-catch-var.js b/test/language/statements/try/early-catch-var.js
new file mode 100644
index 0000000000..51d772c12d
--- /dev/null
+++ b/test/language/statements/try/early-catch-var.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-try-statement-static-semantics-early-errors
+es6id: 13.15.1
+description: >
+    It is a Syntax Error if any element of the BoundNames of CatchParameter
+    also occurs in the VarDeclaredNames of Block.
+info: >
+    Annex B extensions permit re-declarations from VariableStatement, the
+    VariableDeclarationList of a for statement, and the ForBinding of a for-of
+    statement. Bindings from the ForBinding of a for-in statement are
+    restricted regardless of the application of Annex B.
+negative: SyntaxError
+---*/
+
+$ERROR('This code should not be executed.');
+
+try { } catch (x) { for (var x of []) {} }
-- 
GitLab