aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js26
-rw-r--r--test/compress/functions.js170
-rw-r--r--test/compress/ie8.js4
3 files changed, 184 insertions, 16 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 9201d890..f4aa62d4 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -610,6 +610,11 @@ merge(Compressor.prototype, {
function is_immutable(value) {
if (!value) return false;
+ if (value instanceof AST_Assign) {
+ var op = value.operator;
+ return op == "=" ? is_immutable(value.right) : !lazy_op[op.slice(0, -1)];
+ }
+ if (value instanceof AST_Sequence) return is_immutable(value.tail_node());
return value.is_constant() || is_lambda(value) || value instanceof AST_ObjectIdentity;
}
@@ -901,6 +906,7 @@ merge(Compressor.prototype, {
function walk_assign() {
right.walk(tw);
+ var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive_ref(tw, d));
scan_declaration(tw, compressor, left, function() {
return node.right;
}, function(sym, fixed, walk) {
@@ -911,10 +917,7 @@ merge(Compressor.prototype, {
}
var d = sym.definition();
d.assignments++;
- if (fixed
- && !is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive_ref(tw, d))
- && !sym.in_arg
- && safe_to_assign(tw, d)) {
+ if (fixed && !modified && !sym.in_arg && safe_to_assign(tw, d)) {
push_ref(d, sym);
mark(tw, d);
if (d.single_use && left instanceof AST_Destructured) d.single_use = false;
@@ -6299,18 +6302,13 @@ merge(Compressor.prototype, {
var drop_sym = is_var ? can_drop_symbol(def.name) : is_safe_lexical(sym);
if (!drop_sym || !drop_vars || sym.id in in_use_ids) {
if (value && indexOf_assign(sym, def) < 0) {
- var write_only = value.write_only;
value = value.drop_side_effect_free(compressor);
- if (def.value !== value) {
- if (value) {
- AST_Node.warn("Side effects in last use of variable {name} [{file}:{line},{col}]", template(def.name));
- side_effects.push(value);
- }
- value = null;
- trim_defns.push(def);
- } else if (value.write_only !== write_only) {
- value.write_only = write_only;
+ if (value) {
+ AST_Node.warn("Side effects in last use of variable {name} [{file}:{line},{col}]", template(def.name));
+ side_effects.push(value);
}
+ value = null;
+ trim_defns.push(def);
}
var old_def;
if (!value && !(node instanceof AST_Let)) {
diff --git a/test/compress/functions.js b/test/compress/functions.js
index a9a3b8f6..5713a37b 100644
--- a/test/compress/functions.js
+++ b/test/compress/functions.js
@@ -6013,7 +6013,7 @@ issue_4823: {
console.log(typeof function() {
{
function f() {}
- arguments = f();
+ f();
var arguments = function() {};
}
return f && arguments;
@@ -6040,3 +6040,171 @@ drop_unused_self_reference: {
}
expect_stdout: "PASS"
}
+
+reduce_cross_reference_1: {
+ options = {
+ passes: 3,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ unused: true,
+ }
+ input: {
+ (function(a, b) {
+ a = b = function() {};
+ a.p = a;
+ b = a = function() {};
+ b.q = b;
+ })();
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_1_toplevel: {
+ options = {
+ passes: 2,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a = b = function() {};
+ a.p = a;
+ var b = a = function() {};
+ b.q = b;
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_2: {
+ options = {
+ collapse_vars: true,
+ passes: 3,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ unused: true,
+ }
+ input: {
+ (function(a, b) {
+ a = b = function() {};
+ b.p = a;
+ b = a = function() {};
+ a.q = b;
+ })();
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_2_toplevel: {
+ options = {
+ collapse_vars: true,
+ passes: 2,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a = b = function() {};
+ b.p = a;
+ var b = a = function() {};
+ a.q = b;
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_3: {
+ options = {
+ collapse_vars: true,
+ passes: 3,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ unused: true,
+ }
+ input: {
+ (function(a, b) {
+ a = b = function() {};
+ a.p = b;
+ b = a = function() {};
+ b.q = a;
+ })();
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_3_toplevel: {
+ options = {
+ collapse_vars: true,
+ passes: 2,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a = b = function() {};
+ a.p = b;
+ var b = a = function() {};
+ b.q = a;
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_4: {
+ options = {
+ passes: 3,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ unused: true,
+ }
+ input: {
+ (function(a, b) {
+ a = b = function() {};
+ b.p = b;
+ b = a = function() {};
+ a.q = a;
+ })();
+ }
+ expect: {}
+ expect_stdout: true
+}
+
+reduce_cross_reference_4_toplevel: {
+ options = {
+ passes: 2,
+ pure_getters: "strict",
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a = b = function() {};
+ b.p = b;
+ var b = a = function() {};
+ a.q = a;
+ }
+ expect: {}
+ expect_stdout: true
+}
diff --git a/test/compress/ie8.js b/test/compress/ie8.js
index a1daa59c..23532968 100644
--- a/test/compress/ie8.js
+++ b/test/compress/ie8.js
@@ -2653,7 +2653,9 @@ issue_4019: {
try {
console.log("FAIL");
} catch (o) {}
- }, o = (console.log(o.length), ++o);
+ };
+ console.log(o.length),
+ ++o;
}
expect_stdout: "0"
}