Repository: mishoo/UglifyJS (JavaScript)

Issue:
ufuzz failure
```js
// original code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;

function f0(bar_1, b_2) {
    var b = b <<= a, b = (0 === 1 ? a : b) ? {
        c: --b + !function bar() {
            try {
                var b_1 = (c = 1 + c, ([ , 0 ][1] !== "foo") < ("a" ^ 1) <= (c = c + 1, "object" * 24..toString()));
            } catch (bar_1) {
                c = 1 + c, ((25 ^ Infinity) > (false | 5)) >> (22 >= 25) - (bar_1 && (bar_1.var = undefined % true));
                c = 1 + c, !25 - (Infinity < undefined) + (-2 >> "undefined" || -0 | null);
            }
        }(),
        c: --b + (typeof b_2 === "symbol"),
        length: a++ + [ , typeof f2 == "function" && --_calls_ >= 0 && f2((c = 1 + c, ((true === Infinity) > "object" >> 2) * ("b" == null & "" + "c")), 22), 1 === 1 ? a : b, b_2, /[abc4]/g.exec((a++ || b || 5).toString()) ]
    }.foo : --b + +(b && (b.foo -= (-5 + "c" || void "function") & (c = c + 1, -1 <= [ , 0 ][1])));
    var a_1;
}

var arguments_2 = f0(23..toString() in {
    [--b + {}]: (c = c + 1) + (arguments_2 && typeof arguments_2.in == "function" && --_calls_ >= 0 && arguments_2.in(typeof f0 == "function" && --_calls_ >= 0 && f0(0, ..."" + arguments_2))),
    c: --b + []
});

console.log(null, a, b, c, Infinity, NaN, undefined);
```
```js
// uglified code
// (beautified)
var o, c = 10, t = 100, i = 0;

function f0(o, f) {
    var n = n << t ? {
        c: --n + !function bar() {
            try {
                i = 1 + i, i += 1;
            } catch (o) {
                i = 1 + i, o && (o.var = NaN), i = 1 + i;
            }
        }(),
        c: --n + ("symbol" == typeof f),
        length: t++ + [ , "function" == typeof f2 && 0 <= --c && f2((i = 1 + i, 0), 22), t, f, /[abc4]/g.exec("" + (t++ || n || 5)) ]
    }.foo : --n + +(n && (n.foo -= "-5c" & (i += 1, !0)));
}

o = f0((i += 1, o && "function" == typeof o.in && 0 <= --c && o.in(0 <= --c && f0(0, ..."" + o)))), 
console.log(null, t, 8, i, Infinity, NaN, void 0);
```
```
original result:
null 100 8 2 Infinity NaN undefined

uglified result:
null 100 8 1 Infinity NaN undefined
```
```js
// reduced test case (output will differ)

// (beautified)
var b = b <<= 0, b = b ? 0 : console.log(b);
// output: 0
// 
// minify: undefined
// 
// options: {
//   "compress": {
//     "hoist_vars": true,
//     "keep_infinity": true,
//     "passes": 1000000,
//     "unsafe": true
//   },
//   "keep_fnames": true,
//   "toplevel": true,
//   "mangle": {
//     "v8": true
//   },
//   "output": {
//     "v8": true
//   },
//   "validate": true
// }
```
```
minify(options):
{
  "compress": {
    "hoist_vars": true,
    "keep_infinity": true,
    "passes": 1000000,
    "unsafe": true
  },
  "keep_fnames": true,
  "toplevel": true,
  "mangle": {
    "v8": true
  },
  "output": {
    "v8": true
  }
}

Suspicious compress options:
  assignments
  collapse_vars
  conditionals
  dead_code
  evaluate
  join_vars
  passes
  side_effects
```


Discussion:

Patch:
diff --git a/lib/compress.js b/lib/compress.js
index fd0564cb6c3..bcffd8b8ebe 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -9948,9 +9948,9 @@ merge(Compressor.prototype, {
                         operator: self.right.operator + "=",
                         left: self.left,
                         right: self.right.right,
-                    }).optimize(compressor);
+                    });
                 }
-                else if (self.right.right instanceof AST_SymbolRef
+                if (self.right.right instanceof AST_SymbolRef
                     && self.right.right.name == self.left.name
                     && ASSIGN_OPS_COMMUTATIVE[self.right.operator]
                     && !self.right.left.has_side_effects(compressor)) {
@@ -9959,7 +9959,7 @@ merge(Compressor.prototype, {
                         operator: self.right.operator + "=",
                         left: self.left,
                         right: self.right.left,
-                    }).optimize(compressor);
+                    });
                 }
             }
             if ((self.operator == "-=" || self.operator == "+="


Test patch:
diff --git a/test/compress/assignments.js b/test/compress/assignments.js
index 0f87f9a0cc2..5bc971a5063 100644
--- a/test/compress/assignments.js
+++ b/test/compress/assignments.js
@@ -461,3 +461,17 @@ issue_3949_2: {
     }
     expect_stdout: "100"
 }
+
+issue_4521: {
+    options = {
+        assignments: true,
+        dead_code: true,
+    }
+    input: {
+        var a = (a = 42 | a) ? console.log(a) : 0;
+    }
+    expect: {
+        var a = (a |= 42) ? console.log(a) : 0;
+    }
+    expect_stdout: "42"
+}