From c58e174647671ebd504e2255e853e1e1dfeb21ea Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Wed, 21 Apr 2021 01:33:54 +0100 Subject: [PATCH] document various ECMAScript bugs (#4857) --- README.md | 18 ++++++++++++++++++ test/compress/classes.js | 2 +- test/compress/loops.js | 14 +++++++++++++- test/ufuzz/index.js | 15 ++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 914eb562..7f7abae1 100644 --- a/README.md +++ b/README.md @@ -1309,3 +1309,21 @@ To allow for better optimizations, the compiler makes various assumptions: // Actual: { '42': undefined } ``` UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + var await; + async function f() { + class A { + static p = await; + } + } + // SyntaxError: Unexpected reserved word + ``` + UglifyJS may modify the input which in turn may suppress those errors. +- Later versions of JavaScript will throw `SyntaxError` with the following: + ```javascript + var async; + for (async of []); + // SyntaxError: The left-hand side of a for-of loop may not be 'async'. + ``` + UglifyJS may modify the input which in turn may suppress those errors. diff --git a/test/compress/classes.js b/test/compress/classes.js index badcb2e6..ca9ddfdd 100644 --- a/test/compress/classes.js +++ b/test/compress/classes.js @@ -777,7 +777,7 @@ unused_await: { })(); } expect_stdout: true - node_version: ">=12" + node_version: ">=12 <16" } computed_key_side_effects: { diff --git a/test/compress/loops.js b/test/compress/loops.js index 5a66e02c..4ba0d075 100644 --- a/test/compress/loops.js +++ b/test/compress/loops.js @@ -829,6 +829,18 @@ empty_for_in_prop_init: { } for_of: { + input: { + var a = [ "PASS", 42 ]; + a.p = "FAIL"; + for (a of (null, a)) + console.log(a); + } + expect_exact: 'var a=["PASS",42];a.p="FAIL";for(a of(null,a))console.log(a);' + expect_stdout: true + node_version: ">=0.12" +} + +for_async_of: { input: { var async = [ "PASS", 42 ]; async.p = "FAIL"; @@ -837,7 +849,7 @@ for_of: { } expect_exact: 'var async=["PASS",42];async.p="FAIL";for(async of(null,async))console.log(async);' expect_stdout: true - node_version: ">=0.12" + node_version: ">=0.12 <16" } issue_3631_1: { diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index 5c6c2625..5a791f19 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -982,8 +982,17 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn var label = createLabel(canBreak, canContinue); canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK); canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE); - var key = rng(10) ? "key" + loop : getVarName(NO_CONST); var of = SUPPORT.for_of && rng(20) == 0; + var key; + if (rng(10)) { + key = "key" + loop; + } else if (bug_for_of_async && of) { + addAvoidVar("async"); + key = getVarName(NO_CONST); + removeAvoidVar("async"); + } else { + key = getVarName(NO_CONST); + } var init = ""; if (!/^key/.test(key)) { if (!(of && bug_for_of_var) && rng(10) == 0) init = "var "; @@ -1789,7 +1798,9 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) { if (rng(5)) { async = false; generator = false; + if (bug_async_class_await && fixed) addAvoidVar("await"); s += " = " + createExpression(recurmax, NO_COMMA, stmtDepth, fixed ? canThrow : CANNOT_THROW); + if (bug_async_class_await && fixed) removeAvoidVar("await"); generator = save_generator; async = save_async; } @@ -2383,6 +2394,8 @@ if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && typeof sandbox.run_code("a return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter"; }; } +var bug_async_class_await = SUPPORT.async && SUPPORT.class_field && typeof sandbox.run_code("var await; async function f() { class A { static p = await; } }") != "string"; +var bug_for_of_async = SUPPORT.for_await_of && typeof sandbox.run_code("var async; for (async of []);") != "string"; var bug_for_of_var = SUPPORT.for_of && SUPPORT.let && typeof sandbox.run_code("try {} catch (e) { for (var e of []); }") != "string"; if (SUPPORT.destructuring && typeof sandbox.run_code("console.log([ 1 ], {} = 2);") != "string") { beautify_options.output.v8 = true; -- 2.34.1