From: Alex Lam S.L Date: Sun, 26 Mar 2017 08:52:38 +0000 (+0800) Subject: fallthrough should not execute case expression (#1683) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=3276740779077f2ee7b686c4aa7f1bd46fbc1c66;p=UglifyJS.git fallthrough should not execute case expression (#1683) - de-duplicate trailing cases only, avoid all potential side-effects - enable switch statement fuzzing fixes #1680 --- diff --git a/lib/compress.js b/lib/compress.js index 70bbb7fc..8467f96c 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2515,7 +2515,7 @@ merge(Compressor.prototype, { self.expression = best_of_expression(expression, self.expression); } if (compressor.option("dead_code")) { - var blocks = Object.create(null); + var prev_block; var decl = []; var body = []; var default_branch; @@ -2542,31 +2542,21 @@ merge(Compressor.prototype, { continue; } } + var case_side_effects = branch instanceof AST_Case && branch.expression.has_side_effects(compressor); if (aborts(branch)) { - var key = make_node(AST_BlockStatement, branch, branch).print_to_string(); - var block; - if (!fallthrough && (block = blocks[key])) { - block.body = []; - body.splice(body.indexOf(block) + 1, 0, branch); - } else { - body.push(branch); - } + var block = make_node(AST_BlockStatement, branch, branch).print_to_string(); + if (!fallthrough && prev_block === block) body[body.length - 1].body = []; + body.push(branch); + prev_block = block; fallthrough = false; } else { body.push(branch); + prev_block = null; fallthrough = true; } - if (branch instanceof AST_Case && branch.expression.has_side_effects(compressor)) - blocks = Object.create(null); - if (!fallthrough) blocks[key] = branch; } for (; i < len && fallthrough; i++) { branch = self.body[i]; - if (branch instanceof AST_Case) { - exact_match.body.push(make_node(AST_SimpleStatement, branch.expression, { - body: branch.expression - })); - } exact_match.body = exact_match.body.concat(branch.body); fallthrough = !aborts(exact_match); } diff --git a/test/compress/switch.js b/test/compress/switch.js index 481257aa..2025d91b 100644 --- a/test/compress/switch.js +++ b/test/compress/switch.js @@ -23,7 +23,6 @@ constant_switch_2: { } expect: { foo(); - 2; bar(); } } @@ -118,7 +117,6 @@ constant_switch_6: { x(); if (foo) break OUT; y(); - 2; bar(); } } @@ -157,7 +155,6 @@ constant_switch_7: { console.log(x); } y(); - 2; bar(); } } @@ -206,7 +203,6 @@ constant_switch_9: { x(); for (;;) if (foo) break OUT; y(); - 2; bar(); def(); } @@ -481,3 +477,79 @@ issue_1679: { } expect_stdout: true } + +issue_1680_1: { + options = { + dead_code: true, + evaluate: true, + } + input: { + function f(x) { + console.log(x); + return x + 1; + } + switch (2) { + case f(0): + case f(1): + f(2); + case 2: + case f(3): + case f(4): + f(5); + } + } + expect: { + function f(x) { + console.log(x); + return x + 1; + } + switch (2) { + case f(0): + case f(1): + f(2); + case 2: + f(5); + } + } + expect_stdout: [ + "0", + "1", + "2", + "5", + ] +} + +issue_1680_2: { + options = { + dead_code: true, + } + input: { + var a = 100, b = 10; + switch (b) { + case a--: + break; + case b: + var c; + break; + case a: + break; + case a--: + break; + } + console.log(a, b); + } + expect: { + var a = 100, b = 10; + switch (b) { + case a--: + break; + case b: + var c; + break; + case a: + case a--: + } + console.log(a, b); + } + expect_stdout: true +} diff --git a/test/ufuzz.js b/test/ufuzz.js index c56c6224..49236253 100644 --- a/test/ufuzz.js +++ b/test/ufuzz.js @@ -201,7 +201,6 @@ function createStatement(recurmax, canThrow, canBreak, canContinue) { case 6: return createExpression(recurmax) + ';'; case 7: - return ';'; // TODO: disabled until some switch issues are resolved // note: case args are actual expressions // note: default does not _need_ to be last return 'switch (' + createExpression(recurmax) + ') { ' + createSwitchParts(recurmax, 4) + '}';