From: Alex Lam S.L Date: Fri, 18 Dec 2020 01:42:07 +0000 (+0000) Subject: fix corner case in `arguments` (#4398) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=82d2aa4acf1eea742a3b1041223a74b5960d4bfd;p=UglifyJS.git fix corner case in `arguments` (#4398) fixes #4397 --- diff --git a/lib/compress.js b/lib/compress.js index 4279dc7c..8d41ab82 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1048,7 +1048,7 @@ merge(Compressor.prototype, { }); def(AST_Unary, function(tw, descend) { var node = this; - if (!unary_arithmetic[node.operator]) return; + if (!UNARY_POSTFIX[node.operator]) return; var exp = node.expression; if (!(exp instanceof AST_SymbolRef)) { mark_assignment_to_arguments(exp); @@ -1978,7 +1978,7 @@ merge(Compressor.prototype, { extract_candidates(expr.expression); expr.body.forEach(extract_candidates); } else if (expr instanceof AST_Unary) { - if (unary_arithmetic[expr.operator]) { + if (UNARY_POSTFIX[expr.operator]) { candidates.push(hit_stack.slice()); } else { extract_candidates(expr.expression); @@ -3473,8 +3473,6 @@ merge(Compressor.prototype, { }); var lazy_op = makePredicate("&& ||"); - var unary_arithmetic = makePredicate("++ --"); - var unary_side_effects = makePredicate("delete ++ --"); function is_lhs(node, parent) { if (parent instanceof AST_Assign) return parent.left === node && node; @@ -3725,7 +3723,7 @@ merge(Compressor.prototype, { }); var scan_modified = new TreeWalker(function(node) { if (node instanceof AST_Assign) modified(node.left); - if (node instanceof AST_Unary && unary_arithmetic[node.operator]) modified(node.expression); + if (node instanceof AST_Unary && UNARY_POSTFIX[node.operator]) modified(node.expression); }); function modified(node) { if (node instanceof AST_PropAccess) { @@ -4964,7 +4962,7 @@ merge(Compressor.prototype, { return true; } if (node instanceof AST_Unary) { - if (!unary_arithmetic[node.operator]) return; + if (!UNARY_POSTFIX[node.operator]) return; var sym = node.expression; if (!(sym instanceof AST_SymbolRef)) return; mark(sym, true, true); @@ -9885,7 +9883,7 @@ merge(Compressor.prototype, { && is_arguments(def = expr.definition()) && prop instanceof AST_Number && (fn = def.scope) === find_lambda() - && !(assigned && fn.uses_arguments === "d")) { + && fn.uses_arguments < (assigned ? 2 : 3)) { var index = prop.value; if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") { if (!def.deleted) def.deleted = []; diff --git a/lib/scope.js b/lib/scope.js index a285f919..187309ca 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -100,6 +100,8 @@ SymbolDef.prototype = { }, }; +var unary_side_effects = makePredicate("delete ++ --"); + AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { options = defaults(options, { cache: null, @@ -256,8 +258,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } else if (name == "arguments" && sym.orig[0] instanceof AST_SymbolFunarg && !(sym.scope instanceof AST_Arrow)) { - if (!(tw.parent() instanceof AST_PropAccess)) { - sym.scope.uses_arguments = "d"; + var parent = tw.parent(); + if (parent instanceof AST_Assign && parent.left === node + || parent instanceof AST_Unary && unary_side_effects[parent.operator]) { + sym.scope.uses_arguments = 3; + } else if (sym.scope.uses_arguments < 2 + && !(parent instanceof AST_PropAccess && parent.expression === node)) { + sym.scope.uses_arguments = 2; } else if (!sym.scope.uses_arguments) { sym.scope.uses_arguments = true; } diff --git a/test/compress/arguments.js b/test/compress/arguments.js index 4b09a99a..c3ef226e 100644 --- a/test/compress/arguments.js +++ b/test/compress/arguments.js @@ -851,3 +851,23 @@ issue_4291_2: { } expect_stdout: "PASS 42 1" } + +issue_4397: { + options = { + arguments: true, + keep_fargs: "strict", + } + input: { + console.log(typeof function() { + arguments += 0; + return arguments[0]; + }()); + } + expect: { + console.log(typeof function() { + arguments += 0; + return arguments[0]; + }()); + } + expect_stdout: "string" +}