From 7b43b6396f958f9fad7ce31882db449542aa758c Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 16 Mar 2021 10:14:24 +0000 Subject: [PATCH] ensure valid generated cases in `--reduce-test` (#4787) closes #4786 --- test/reduce.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/test/reduce.js b/test/reduce.js index 6f413789..231e9586 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -208,12 +208,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) } if (node.expression instanceof U.AST_Function) { // hoist and return expressions from the IIFE function expression - var body = node.expression.body; - node.expression.body = []; var seq = []; - body.forEach(function(node) { + node.expression.body.forEach(function(node) { var expr = expr instanceof U.AST_Exit ? node.value : node.body; - if (expr instanceof U.AST_Node && !U.is_statement(expr)) { + if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) { // collect expressions from each statements' body seq.push(expr); } @@ -264,7 +262,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) CHANGED = true; return List.skip; default: - if (!has_exit(node)) { + if (!has_exit(node) && can_hoist(node)) { // hoist function declaration body var body = node.body; node.body = []; @@ -381,11 +379,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) if (node.body instanceof U.AST_Call && node.body.expression instanceof U.AST_Function) { // hoist simple statement IIFE function expression body node.start._permute++; - if (!has_exit(node.body.expression)) { - var body = node.body.expression.body; - node.body.expression.body = []; + if (!has_exit(node.body.expression) && can_hoist(node.body.expression)) { CHANGED = true; - return List.splice(body); + return List.splice(node.body.expression.body); } } } @@ -673,6 +669,20 @@ function has_loopcontrol(body, loop, label) { return found; } +function can_hoist(body) { + var found = false; + body.walk(new U.TreeWalker(function(node) { + if (found) return true; + if (node instanceof U.AST_NewTarget) return found = true; + if (node instanceof U.AST_Scope) { + if (node === body) return; + return true; + } + if (node instanceof U.AST_Super) return found = true; + })); + return !found; +} + function is_timed_out(result) { return sandbox.is_error(result) && /timed out/.test(result.message); } -- 2.34.1