fix corner case in side_effects (#4752)

fixes #4751
This commit is contained in:
Alex Lam S.L
2021-03-07 20:19:51 +00:00
committed by GitHub
parent 31e7d25cad
commit f52b0e7c31
9 changed files with 277 additions and 45 deletions

View File

@@ -4797,15 +4797,9 @@ merge(Compressor.prototype, {
|| this.right.has_side_effects(compressor);
});
def(AST_Binary, function(compressor) {
var lhs = this.left;
if (lhs.has_side_effects(compressor)) return true;
var rhs = this.right;
var op = this.operator;
if (!rhs.has_side_effects(compressor)) return op == "in" && !is_object(rhs);
if (op == "&&" && rhs instanceof AST_PropAccess && lhs.equivalent_to(rhs.expression)) {
return rhs instanceof AST_Sub && rhs.property.has_side_effects(compressor);
}
return true;
return this.left.has_side_effects(compressor)
|| this.right.has_side_effects(compressor)
|| this.operator == "in" && !is_object(this.right);
});
def(AST_Block, function(compressor) {
return any(this.body, compressor);
@@ -7220,17 +7214,6 @@ merge(Compressor.prototype, {
if (!rhs) return left.drop_side_effect_free(compressor, first_in_statement);
if (lazy_op[op] && rhs.has_side_effects(compressor)) {
var node = this;
if (op == "&&"
&& rhs instanceof AST_PropAccess
&& left.equivalent_to(rhs.expression)
&& !left.has_side_effects(compressor)) {
var prop = rhs instanceof AST_Sub
&& rhs.property.drop_side_effect_free(compressor, first_in_statement);
if (!prop) return left.drop_side_effect_free(compressor, first_in_statement);
node = node.clone();
node.right = prop;
return node.drop_side_effect_free(compressor, first_in_statement);
}
if (rhs !== right) {
node = node.clone();
node.right = rhs.drop_side_effect_free(compressor);
@@ -7242,13 +7225,12 @@ merge(Compressor.prototype, {
right: node.right,
});
return first_in_statement ? best_of_statement(node, negated) : best_of_expression(node, negated);
} else {
var lhs = left.drop_side_effect_free(compressor, first_in_statement);
if (!lhs) return rhs;
rhs = rhs.drop_side_effect_free(compressor);
if (!rhs) return lhs;
return make_sequence(this, [ lhs, rhs ]);
}
var lhs = left.drop_side_effect_free(compressor, first_in_statement);
if (!lhs) return rhs;
rhs = rhs.drop_side_effect_free(compressor);
if (!rhs) return lhs;
return make_sequence(this, [ lhs, rhs ]);
});
def(AST_Call, function(compressor, first_in_statement) {
var self = this;

View File

@@ -2862,7 +2862,7 @@ lvalues_def: {
expect: {
var a = 0, b = 1;
a = b++, b = +void 0;
a && a++;
a && a[a++];
console.log(a, b);
}
expect_stdout: true
@@ -5096,7 +5096,7 @@ issue_2878: {
}
b = f2();
a = 1;
b && b[console];
b && b.b;
f2();
})();
console.log(c);
@@ -5109,7 +5109,7 @@ issue_2878: {
}
b = f2(),
a = 1,
b && console,
b && b.b,
f2();
})(),
console.log(c);
@@ -6544,7 +6544,7 @@ issue_3520: {
(function f() {
c = 0;
var i = void 0;
var f = f && f[console && i];
var f = f && f[i];
})();
a += b;
c && b++;
@@ -6558,7 +6558,7 @@ issue_3520: {
for (var i = 2; --i >= 0;) {
(function() {
c = 0;
var f = f && f[console && void 0];
var f = f && f[void 0];
})();
a += b;
c && b++;

View File

@@ -2726,8 +2726,8 @@ issue_3944: {
}
expect: {
void function f() {
while (b = void 0, b = console.log(0 == (b && b.p)), void 0);
var b;
while (a = 0 == (a = void 0), console.log(a), void 0);
var a;
f;
}();
}

View File

@@ -2923,13 +2923,14 @@ issue_4568: {
issue_4729: {
options = {
ie8: true,
pure_getters: true,
toplevel: true,
unused: true,
}
input: {
try {
f;
} catch(e) {
} catch (e) {
var a = a && a[function f() {}];
console.log("PASS");
}
@@ -2937,7 +2938,7 @@ issue_4729: {
expect: {
try {
f;
} catch(e) {
} catch (e) {
(function f() {});
console.log("PASS");
}

View File

@@ -2723,7 +2723,7 @@ issue_4135: {
var c = function() {
var d = 0;
function f() {
d && d[console];
d && d.p;
}
f();
this;
@@ -2735,7 +2735,7 @@ issue_4135: {
0;
a++;
if (!a)
c = (a++, c = 0, void (c && console));
c = (a++, c = 0, void (c && c.p));
var c;
console.log(a, -1, c);
}

View File

@@ -1220,6 +1220,104 @@ drop_arguments: {
expect_stdout: "PASS"
}
lvalues_def: {
options = {
collapse_vars: true,
pure_getters: true,
side_effects: true,
unused: true,
}
input: {
var a = 0, b = 1;
var a = b++, b = +function() {}();
a && a[a++];
console.log(a, b);
}
expect: {
var a = 0, b = 1;
a = b++, b = +void 0;
a && a++;
console.log(a, b);
}
expect_stdout: true
}
side_effects_assign: {
options = {
evaluate: true,
pure_getters: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
}
input: {
var a = typeof void (a && a.in == 1, 0);
console.log(a);
}
expect: {
var a = "undefined";
console.log(a);
}
expect_stdout: "undefined"
}
issue_2062: {
options = {
booleans: true,
collapse_vars: true,
conditionals: true,
pure_getters: true,
side_effects: true,
}
input: {
var a = 1;
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
console.log(a);
}
expect: {
var a = 1;
a || (a++, a--), a++, a--;
console.log(a);
}
expect_stdout: "1"
}
issue_2878: {
options = {
collapse_vars: true,
pure_getters: true,
sequences: true,
}
input: {
var c = 0;
(function(a, b) {
function f2() {
if (a) c++;
}
b = f2();
a = 1;
b && b.b;
f2();
})();
console.log(c);
}
expect: {
var c = 0;
(function(a, b) {
function f2() {
if (a) c++;
}
b = f2(),
a = 1,
f2();
})(),
console.log(c);
}
expect_stdout: "1"
}
issue_3427: {
options = {
assignments: true,
@@ -1242,6 +1340,74 @@ issue_3427: {
expect_stdout: true
}
issue_3490_1: {
options = {
conditionals: true,
dead_code: true,
inline: true,
pure_getters: true,
sequences: true,
side_effects: true,
toplevel: true,
}
input: {
var b = 42, c = "FAIL";
if ({
3: function() {
var a;
return (a && a.p) < this;
}(),
}) c = "PASS";
if (b) while ("" == typeof d);
console.log(c, b);
}
expect: {
var b = 42, c = "FAIL";
if (function() {
var a;
}(), c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}
expect_stdout: "PASS 42"
}
issue_4135: {
options = {
evaluate: true,
inline: true,
merge_vars: true,
pure_getters: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 0, b = 0;
--b;
a++;
if (!a)
var c = function() {
var d = 0;
function f() {
d && d.p;
}
f();
this;
}(a++);
console.log(a, b, c);
}
expect: {
var a = 0;
0;
a++;
if (!a)
var c = void a++;
console.log(a, -1, c);
}
expect_stdout: "1 -1 undefined"
}
issue_4440: {
options = {
pure_getters: "strict",
@@ -1270,3 +1436,57 @@ issue_4440: {
}
expect_stdout: "PASS"
}
issue_4730_1: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var a;
console.log("PASS") + (a && a[a.p]);
}
expect: {
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_4730_2: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var a;
!console.log("PASS") || a && a[a.p];
}
expect: {
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_4751: {
options = {
pure_getters: true,
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
},
};
o && o.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
},
};
}
}

View File

@@ -2554,7 +2554,7 @@ side_effects_assign: {
console.log(a);
}
expect: {
var a = "undefined";
var a = typeof void (a && a.in);
console.log(a);
}
expect_stdout: "undefined"
@@ -2595,7 +2595,9 @@ pure_getters_2: {
var a;
var a = a && a.b;
}
expect: {}
expect: {
var a = a && a.b;
}
}
pure_getters_3: {

View File

@@ -754,12 +754,12 @@ issue_2062: {
}
input: {
var a = 1;
if ([ a || a++ + a--, a++ + a--, a && a[console] ]);
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
console.log(a);
}
expect: {
var a = 1;
a || (a++, a--), a++, --a && console;
a || (a++, a--), a++, --a && a.var;
console.log(a);
}
expect_stdout: "1"
@@ -1097,7 +1097,7 @@ issue_3490_1: {
if ({
3: function() {
var a;
return (a && a[console]) < this;
return (a && a.p) < this;
}(),
}) c = "PASS";
if (b) while ("" == typeof d);
@@ -1107,7 +1107,7 @@ issue_3490_1: {
var b = 42, c = "FAIL";
if (function() {
var a;
a && console;
a && a.p;
}(), c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}

View File

@@ -561,6 +561,7 @@ drop_side_effect_free_call: {
issue_4730_1: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
@@ -569,13 +570,15 @@ issue_4730_1: {
}
expect: {
var a;
console.log("PASS");
console.log("PASS"),
a && a[a.p];
}
expect_stdout: "PASS"
}
issue_4730_2: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
@@ -584,7 +587,31 @@ issue_4730_2: {
}
expect: {
var a;
console.log("PASS");
!console.log("PASS") || a && a[a.p];
}
expect_stdout: "PASS"
}
issue_4751: {
options = {
pure_getters: "strict",
side_effects: true,
}
input: {
var o = {
get p() {
console.log("PASS");
},
};
o && o.p;
}
expect: {
var o = {
get p() {
console.log("PASS");
},
};
o && o.p;
}
expect_stdout: "PASS"
}