Bug 1146644 - Don't assert compiling a for-loop with a const loop-variable declaration. r=shu
☠☠ backed out by 67f8d63b2cad ☠ ☠
authorJeff Walden <jwalden@mit.edu>
Thu, 26 Mar 2015 14:12:31 -0400
changeset 266444 031ded170326a79322fce1972f29b0d6683bde1c
parent 266443 acbab9e2269188baa30e8bb06b770e810dcf9d83
child 266445 2d59ec36a2e48587ac39d066122695df612575fc
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1146644
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1146644 - Don't assert compiling a for-loop with a const loop-variable declaration. r=shu
js/src/frontend/FoldConstants.cpp
js/src/tests/ecma_6/LexicalEnvironment/const-declaration-in-for-loop.js
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -302,18 +302,21 @@ ContainsHoistedDeclaration(ExclusiveCont
         }
 
         ParseNode *loopBody = node->pn_right;
         return ContainsHoistedDeclaration(cx, loopBody, result);
       }
 
       case PNK_LETBLOCK: {
         MOZ_ASSERT(node->isArity(PN_BINARY));
-        MOZ_ASSERT(node->pn_left->isKind(PNK_LET));
         MOZ_ASSERT(node->pn_right->isKind(PNK_LEXICALSCOPE));
+        MOZ_ASSERT(node->pn_left->isKind(PNK_LET) ||
+                   (node->pn_left->isKind(PNK_CONST) && node->pn_right->pn_expr->isKind(PNK_FOR)),
+                   "a let-block's left half is its declarations: ordinarily a PNK_LET node but "
+                   "PNK_CONST in the weird case of |for (const x ...)|");
         return ContainsHoistedDeclaration(cx, node->pn_right, result);
       }
 
       case PNK_LEXICALSCOPE: {
         MOZ_ASSERT(node->isArity(PN_NAME));
         ParseNode *expr = node->pn_expr;
 
         if (expr->isKind(PNK_FOR))
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/LexicalEnvironment/const-declaration-in-for-loop.js
@@ -0,0 +1,95 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = "const-declaration-in-for-loop.js";
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 1146644;
+var summary =
+  "Don't crash compiling a non-body-level for-loop whose loop declaration is " +
+  "a const";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+for (const a1 = 3; false; )
+  continue;
+
+Function(`for (const a2 = 3; false; )
+            continue;
+         `)();
+
+if (true)
+{
+  for (const a3 = 3; false; )
+    continue;
+}
+
+Function(`if (true)
+          {
+            for (const a4 = 3; false; )
+              continue;
+          }`)();
+
+// We don't support for (const ... in ...) or for (const ... of ...) yet.  When
+// we do, these all should start passing without throwing a syntax error, and
+// we can remove the try/catch here, and the ultimate throw-canary forcing this
+// test to be updated.
+try
+{
+
+evaluate(`for (const a5 of [])
+            continue;`);
+
+Function(`for (const a6 of [])
+            continue;`)();
+
+evaluate(`if (true)
+          {
+            for (const a7 of [])
+              continue;
+          }`);
+
+Function(`if (true)
+          {
+            for (const a8 of [])
+              continue;
+          }`)();
+
+evaluate(`for (const a9 in {})
+            continue;`);
+
+Function(`for (const a10 in {})
+            continue;`)();
+
+evaluate(`if (true)
+          {
+            for (const a11 in {})
+              continue;
+          }`);
+
+Function(`if (true)
+          {
+            for (const a12 in {})
+              continue;
+          }`)();
+
+throw new Error("Congratulations on making for (const … in/of …) work!  " +
+                "Please remove the try/catch and this throw.");
+}
+catch (e)
+{
+  assertEq(e instanceof SyntaxError, true,
+           "unexpected error: expected SyntaxError, got " + e);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("Tests complete");