fix corner case in reduce_vars (#4189)

fixes #4188
This commit is contained in:
Alex Lam S.L
2020-10-07 15:01:39 +01:00
committed by GitHub
parent bc6e105174
commit 9c0feb69e5
3 changed files with 80 additions and 18 deletions

View File

@@ -354,6 +354,13 @@ merge(Compressor.prototype, {
return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
}
function cross_scope(def, sym) {
do {
if (def === sym) return false;
if (sym instanceof AST_Scope) return true;
} while (sym = sym.parent_scope);
}
(function(def) {
def(AST_Node, noop);
@@ -506,6 +513,7 @@ merge(Compressor.prototype, {
function ref_once(compressor, def) {
return compressor.option("unused")
&& !def.scope.pinned()
&& def.single_use !== false
&& def.references.length - def.recursive_refs == 1;
}
@@ -840,11 +848,13 @@ merge(Compressor.prototype, {
&& d.orig[0] instanceof AST_SymbolDefun) {
tw.loop_ids[d.id] = tw.in_loop;
}
var value;
if (d.fixed === undefined || !safe_to_read(tw, d)) {
if (d.fixed === false) {
var redef = d.redefined();
if (redef && cross_scope(d.scope, this.scope)) redef.single_use = false;
} else if (d.fixed === undefined || !safe_to_read(tw, d)) {
d.fixed = false;
} else if (d.fixed) {
value = this.fixed_value();
var value = this.fixed_value();
var recursive = recursive_ref(tw, d);
if (recursive) {
d.recursive_refs++;
@@ -5140,13 +5150,6 @@ merge(Compressor.prototype, {
return rhs.right;
}
function cross_scope(def, sym) {
do {
if (def === sym) return false;
if (sym instanceof AST_Scope) return true;
} while (sym = sym.parent_scope);
}
function scan_ref_scoped(node, descend, init) {
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
var def = node.left.definition();
@@ -8310,13 +8313,6 @@ merge(Compressor.prototype, {
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
}
function find_variable(compressor, name) {
var level = 0, node;
while (node = compressor.parent(level++)) {
if (node.variables) return node.find_variable(name);
}
}
OPT(AST_Undefined, function(self, compressor) {
if (compressor.option("unsafe_undefined")) {
var undef = find_scope(compressor).find_variable("undefined");

View File

@@ -196,7 +196,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
var sym = node.scope.find_variable(name);
if (!sym) {
sym = self.def_global(node);
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
} else if (name == "arguments" && sym.scope instanceof AST_Lambda) {
sym.scope.uses_arguments = true;
}
if (name == "eval") {

View File

@@ -7535,3 +7535,69 @@ global_assign: {
}
expect_stdout: "PASS"
}
issue_4188_1: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
try {
while (A)
var a = function() {}, b = a;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
})();
}
expect: {
(function() {
try {
while (A)
var a = function() {}, b = a;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
})();
}
expect_stdout: "object undefined"
}
issue_4188_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
try {
throw 42;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
while (!console)
var a = function() {}, b = a;
})();
}
expect: {
(function() {
try {
throw 42;
} catch (a) {
console.log(function() {
return typeof a;
}(), typeof b);
}
while (!console)
var a = function() {}, b = a;
})();
}
expect_stdout: "number undefined"
}