Repository: mishoo/UglifyJS (JavaScript)

Issue:
ufuzz failure
```js
// original code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;

function f0({
    [++a]: undefined_2,
    "": Infinity_1,
    length: bar
}, a_1, a_2) {
    if (a_1) {} else {
        return typeof ((c = c + 1) + 23..toString());
    }
    L12769: for (var brake4 = 5; typeof Infinity_1 == "function" && --_calls_ >= 0 && Infinity_1(23..toString(), a++ + 1, --b + -b) && brake4 > 0; --brake4) {
        L12770: {}
    }
}

var bar_2 = f0({
    [typeof f2 == "function" && --_calls_ >= 0 && f2(null, "object", [])]: "b",
    length: --b + a++
}, b = a);

console.log(null, a, b, c, Infinity, NaN, undefined);
```
```js
// uglified code
// (beautified)
var t = 10, l = 100, e = 10, u = 0;

!function({
    [++l]: n,
    "": o
}) {
    if (!(e = l)) {
        return u += 1;
    }
    for (var f = 5; "function" == typeof o && 0 <= --t && o("23", 1 + l++, --e - e) && 0 < f; --f) {}
}({
    ["function" == typeof f2 && 0 <= --t && f2(null, "object", [])]: "b",
    length: --e + l++
}), console.log(null, l, e, u, 1 / 0, NaN, void 0);
```
```
original result:
null 102 101 0 Infinity NaN undefined

uglified result:
null 102 102 0 Infinity NaN undefined
```
```js
// reduced test case (output will differ)

// (beautified)
var a = 0;

function f0({
    [++a]: undefined_2
}, a_1) {
    if (a_1) {} else {
        return 0;
    }
    0();
}

f0("b", a);
// output: 
// minify: TypeError: 0 is not a function
// options: {
//   "compress": {
//     "passes": 1000000,
//     "unsafe": true
//   },
//   "toplevel": true,
//   "output": {
//     "v8": true
//   },
//   "validate": true
// }
```
```
minify(options):
{
  "compress": {
    "passes": 1000000,
    "unsafe": true
  },
  "toplevel": true,
  "output": {
    "v8": true
  }
}

Suspicious compress options:
  collapse_vars
  passes
  reduce_vars
  unused

Suspicious options:
  toplevel
```


Discussion:

Patch:
diff --git a/lib/compress.js b/lib/compress.js
index 90488807aeb..601f39f0ac0 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1825,7 +1825,11 @@ merge(Compressor.prototype, {
                             name: sym,
                             value: arg
                         }));
-                        if (sym instanceof AST_Destructured) continue;
+                        if (sym instanceof AST_Destructured) {
+                            if (!sym.match_symbol(return_false)) continue;
+                            candidates.length = 0;
+                            break;
+                        }
                         if (sym.name in names) continue;
                         names[sym.name] = true;
                         if (!arg) {


Test patch:
diff --git a/test/compress/destructured.js b/test/compress/destructured.js
index bbe62a71741..f8e8090d8c7 100644
--- a/test/compress/destructured.js
+++ b/test/compress/destructured.js
@@ -1591,3 +1591,28 @@ issue_4301: {
     expect_stdout: true
     node_version: ">=6"
 }
+
+issue_4308: {
+    options = {
+        collapse_vars: true,
+        unused: true,
+    }
+    input: {
+        var a = "PASS";
+        console.log(function({
+            [a = "FAIL"]: b
+        }, c) {
+            return c;
+        }(0, a));
+    }
+    expect: {
+        var a = "PASS";
+        console.log(function({
+            [a = "FAIL"]: b
+        }, c) {
+            return c;
+        }(0, a));
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}