Skip to content

Commit 69f4e3a

Browse files
authored
fix corner case in reduce_vars (#5913)
fixes #5912
1 parent 4661b34 commit 69f4e3a

File tree

4 files changed

+225
-20
lines changed

4 files changed

+225
-20
lines changed

lib/compress.js

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -646,14 +646,12 @@ Compressor.prototype.compress = function(node) {
646646
scope.may_call_this = undefined;
647647
}
648648

649-
function push(tw, sequential) {
649+
function push(tw, sequential, conditional) {
650650
var defined_ids = Object.create(tw.defined_ids);
651-
var safe_ids = Object.create(tw.safe_ids);
652-
if (!sequential) {
653-
defined_ids.seq = Object.create(null);
654-
safe_ids.seq = {};
655-
}
651+
if (!sequential || conditional) defined_ids.seq = Object.create(null);
656652
tw.defined_ids = defined_ids;
653+
var safe_ids = Object.create(tw.safe_ids);
654+
if (!sequential) safe_ids.seq = {};
657655
tw.safe_ids = safe_ids;
658656
}
659657

@@ -855,7 +853,7 @@ Compressor.prototype.compress = function(node) {
855853
var scanner = new TreeWalker(function(node) {
856854
if (node instanceof AST_DefaultValue) {
857855
reset_flags(node);
858-
push(tw, true);
856+
push(tw, true, true);
859857
node.value.walk(tw);
860858
pop(tw);
861859
var save = fixed;
@@ -1042,7 +1040,7 @@ Compressor.prototype.compress = function(node) {
10421040
return walk_lazy();
10431041
}
10441042
var safe = safe_to_read(tw, ld);
1045-
if (lazy) push(tw, true);
1043+
if (lazy) push(tw, true, true);
10461044
right.walk(tw);
10471045
if (lazy) pop(tw);
10481046
if (safe && !left.in_arg && safe_to_assign(tw, ld)) {
@@ -1127,7 +1125,7 @@ Compressor.prototype.compress = function(node) {
11271125
function walk_lazy() {
11281126
if (!lazy) return;
11291127
left.walk(tw);
1130-
push(tw, true);
1128+
push(tw, true, true);
11311129
right.walk(tw);
11321130
pop(tw);
11331131
return true;
@@ -1136,7 +1134,7 @@ Compressor.prototype.compress = function(node) {
11361134
def(AST_Binary, function(tw) {
11371135
if (!lazy_op[this.operator]) return;
11381136
this.left.walk(tw);
1139-
push(tw, true);
1137+
push(tw, true, true);
11401138
this.right.walk(tw);
11411139
pop(tw);
11421140
return true;
@@ -1166,7 +1164,7 @@ Compressor.prototype.compress = function(node) {
11661164
}
11671165
exp.walk(tw);
11681166
var optional = node.optional;
1169-
if (optional) push(tw, true);
1167+
if (optional) push(tw, true, true);
11701168
node.args.forEach(function(arg) {
11711169
arg.walk(tw);
11721170
});
@@ -1251,16 +1249,16 @@ Compressor.prototype.compress = function(node) {
12511249
});
12521250
def(AST_Conditional, function(tw) {
12531251
this.condition.walk(tw);
1254-
push(tw, true);
1252+
push(tw, true, true);
12551253
this.consequent.walk(tw);
12561254
pop(tw);
1257-
push(tw, true);
1255+
push(tw, true, true);
12581256
this.alternative.walk(tw);
12591257
pop(tw);
12601258
return true;
12611259
});
12621260
def(AST_DefaultValue, function(tw) {
1263-
push(tw, true);
1261+
push(tw, true, true);
12641262
this.value.walk(tw);
12651263
pop(tw);
12661264
this.name.walk(tw);
@@ -1349,11 +1347,11 @@ Compressor.prototype.compress = function(node) {
13491347
});
13501348
def(AST_If, function(tw) {
13511349
this.condition.walk(tw);
1352-
push(tw, true);
1350+
push(tw, true, true);
13531351
this.body.walk(tw);
13541352
pop(tw);
13551353
if (this.alternative) {
1356-
push(tw, true);
1354+
push(tw, true, true);
13571355
this.alternative.walk(tw);
13581356
pop(tw);
13591357
}
@@ -1396,7 +1394,7 @@ Compressor.prototype.compress = function(node) {
13961394
var expr = node.expression;
13971395
if (node.optional) {
13981396
expr.walk(tw);
1399-
push(tw, true);
1397+
push(tw, true, true);
14001398
node.property.walk(tw);
14011399
pop(tw);
14021400
} else {
@@ -1420,15 +1418,15 @@ Compressor.prototype.compress = function(node) {
14201418
branch.expression.walk(tw);
14211419
if (first) {
14221420
first = false;
1423-
push(tw, true);
1421+
push(tw, true, true);
14241422
}
14251423
});
14261424
if (!first) pop(tw);
14271425
walk_body(node, tw);
14281426
return true;
14291427
});
14301428
def(AST_SwitchBranch, function(tw) {
1431-
push(tw, true);
1429+
push(tw, true, true);
14321430
walk_body(this, tw);
14331431
pop(tw);
14341432
return true;
@@ -1567,7 +1565,7 @@ Compressor.prototype.compress = function(node) {
15671565
walk_body(node, tw);
15681566
pop(tw);
15691567
if (node.bcatch) {
1570-
push(tw, true);
1568+
push(tw, true, true);
15711569
node.bcatch.walk(tw);
15721570
pop(tw);
15731571
}

test/compress/optional-chains.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,3 +693,35 @@ issue_5905: {
693693
expect_stdout: "PASS"
694694
node_version: ">=14"
695695
}
696+
697+
issue_5912: {
698+
options = {
699+
pure_getters: "strict",
700+
reduce_vars: true,
701+
side_effects: true,
702+
}
703+
input: {
704+
var a, b = {};
705+
b = b.p;
706+
a?.[b.q];
707+
try {
708+
b.r;
709+
console.log("FAIL");
710+
} catch (e) {
711+
console.log("PASS");
712+
}
713+
}
714+
expect: {
715+
var a, b = {};
716+
b = b.p;
717+
a?.[b.q];
718+
try {
719+
b.r;
720+
console.log("FAIL");
721+
} catch (e) {
722+
console.log("PASS");
723+
}
724+
}
725+
expect_stdout: "PASS"
726+
node_version: ">=14"
727+
}

test/compress/side_effects.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,3 +967,104 @@ issue_5860_keep_3: {
967967
}
968968
expect_stdout: "PASS"
969969
}
970+
971+
issue_5912_1: {
972+
options = {
973+
pure_getters: "strict",
974+
reduce_vars: true,
975+
side_effects: true,
976+
}
977+
input: {
978+
var a = {};
979+
a = a.p;
980+
console || a.q;
981+
try {
982+
a.r;
983+
console.log("FAIL");
984+
} catch (e) {
985+
console.log("PASS");
986+
}
987+
}
988+
expect: {
989+
var a = {};
990+
a = a.p;
991+
console || a.q;
992+
try {
993+
a.r;
994+
console.log("FAIL");
995+
} catch (e) {
996+
console.log("PASS");
997+
}
998+
}
999+
expect_stdout: "PASS"
1000+
}
1001+
1002+
issue_5912_2: {
1003+
options = {
1004+
pure_getters: "strict",
1005+
reduce_vars: true,
1006+
side_effects: true,
1007+
}
1008+
input: {
1009+
var a = {};
1010+
a = a.p;
1011+
if (!console) a.q;
1012+
try {
1013+
a.r;
1014+
console.log("FAIL");
1015+
} catch (e) {
1016+
console.log("PASS");
1017+
}
1018+
}
1019+
expect: {
1020+
var a = {};
1021+
a = a.p;
1022+
if (!console) a.q;
1023+
try {
1024+
a.r;
1025+
console.log("FAIL");
1026+
} catch (e) {
1027+
console.log("PASS");
1028+
}
1029+
}
1030+
expect_stdout: "PASS"
1031+
}
1032+
1033+
issue_5912_3: {
1034+
options = {
1035+
pure_getters: "strict",
1036+
reduce_vars: true,
1037+
side_effects: true,
1038+
}
1039+
input: {
1040+
var a = {};
1041+
a = a.p;
1042+
try {
1043+
console;
1044+
} catch (e) {
1045+
a.q;
1046+
}
1047+
try {
1048+
a.r;
1049+
console.log("FAIL");
1050+
} catch (e) {
1051+
console.log("PASS");
1052+
}
1053+
}
1054+
expect: {
1055+
var a = {};
1056+
a = a.p;
1057+
try {
1058+
console;
1059+
} catch (e) {
1060+
a.q;
1061+
}
1062+
try {
1063+
a.r;
1064+
console.log("FAIL");
1065+
} catch (e) {
1066+
console.log("PASS");
1067+
}
1068+
}
1069+
expect_stdout: "PASS"
1070+
}

test/compress/switches.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,3 +1798,77 @@ issue_5892_2: {
17981798
}
17991799
expect_stdout: "PASS"
18001800
}
1801+
1802+
issue_5912_1: {
1803+
options = {
1804+
pure_getters: "strict",
1805+
reduce_vars: true,
1806+
side_effects: true,
1807+
}
1808+
input: {
1809+
var a = {};
1810+
a = a.p;
1811+
switch (console) {
1812+
case 42:
1813+
a.q;
1814+
}
1815+
try {
1816+
a.r;
1817+
console.log("FAIL");
1818+
} catch (e) {
1819+
console.log("PASS");
1820+
}
1821+
}
1822+
expect: {
1823+
var a = {};
1824+
a = a.p;
1825+
switch (console) {
1826+
case 42:
1827+
a.q;
1828+
}
1829+
try {
1830+
a.r;
1831+
console.log("FAIL");
1832+
} catch (e) {
1833+
console.log("PASS");
1834+
}
1835+
}
1836+
expect_stdout: "PASS"
1837+
}
1838+
1839+
issue_5912_2: {
1840+
options = {
1841+
pure_getters: "strict",
1842+
reduce_vars: true,
1843+
side_effects: true,
1844+
}
1845+
input: {
1846+
var a, b = {};
1847+
b = b.p;
1848+
switch (a) {
1849+
case void 0:
1850+
case b.q:
1851+
}
1852+
try {
1853+
b.r;
1854+
console.log("FAIL");
1855+
} catch (e) {
1856+
console.log("PASS");
1857+
}
1858+
}
1859+
expect: {
1860+
var a, b = {};
1861+
b = b.p;
1862+
switch (a) {
1863+
case void 0:
1864+
case b.q:
1865+
}
1866+
try {
1867+
b.r;
1868+
console.log("FAIL");
1869+
} catch (e) {
1870+
console.log("PASS");
1871+
}
1872+
}
1873+
expect_stdout: "PASS"
1874+
}

0 commit comments

Comments
 (0)