Repository: mishoo/UglifyJS (JavaScript)

Issue:
ufuzz failure
```js
// original code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;

{
    var a_2 = function f0(c, a) {
        return a++ + ++a;
        {
            --b + (typeof f2 == "function" && --_calls_ >= 0 && f2());
        }
    }("object", function arguments_2() {}, this);
}

try {
} finally {
    {
        var brake8 = 5;
        while (a_2 && --brake8 > 0) {
            var expr9 = (c = c + 1) + {
                0: a_2 && a_2.b,
                c: a++ + (1 === 1 ? a : b),
                var: (c = c + 1) + {
                    0: a++ + {
                        a: --b + a_2,
                        "-2": --b + {
                            in: (c = 1 + c, (a_2 = 25 % -1) || 4 == this || undefined << null >>> ("c" << 2)),
                            "": (c = 1 + c, (-0 > 24..toString() & -0 <= "undefined") + (("" && 25) >>> undefined + -0)),
                            "": (c = 1 + c, 23..toString() * 1 === "object" < ([ , 0 ].length === 2) | (this === 1) > ("bar" < -0)),
                            "": (c = 1 + c, ~((a_2 = 1 >> 5) <= -4 / -2)),
                            1.5: (c = 1 + c, ("b" == 4 ^ "number" >> 25) < ((null == "a") <= ("undefined" && {})))
                        }[c = 1 + c, 3 % /[a2][^e]+$/ & "undefined" <= "number" && (/[a2][^e]+$/ ^ "b") <= (c = c + 1, 
                        3)],
                        length: (c = c + 1) + void b,
                        "": (c = c + 1) + ((c = 1 + c, (a_2 && (a_2[c = 1 + c, NaN <= "" !== this <= 0 === ("object" < -1 ^ true !== 4)] *= -5 ^ 23..toString())) >= (-4 > 0) !== -3 % "" >> (3 ^ 0)) || 3).toString()[c = 1 + c, 
                        (c = c + 1, [ , 0 ][1]) <= (-5 || null) ^ (a_2 /= (25 === 38..toString()) >= ("undefined" == 3))],
                        a: a_2 = (c = 1 + c, (a_2 && (a_2.var += (a_2 = (0, [ , 0 ][1])) % ("" / -2))) / (2 + ([ , 0 ].length === 2) ^ ("a" && "number")))
                    }.foo,
                    undefined: (c = c + 1) + (0 === 1 ? a : b),
                    b: --b + (b + 1 - .1 - .1 - .1),
                    var: {}[a++ + ~((this == 5) % ("b" > {}) != true >>> "b" >>> (/[a2][^e]+$/ | 2))]
                }[a++ + (typeof f2 == "function" && --_calls_ >= 0 && f2((c = c + 1) + (b %= a), true))],
                null: (c = c + 1) + (typeof bar_2 !== "object"),
                a: 5
            };
            L12722: for (var key9 in expr9) {
                {
                    var a_2_1 = function f1(b) {
                        {
                            var expr11 = --b;
                            L12723: for (var key11 in expr11) {
                                c = 1 + c;
                                var bar_2 = expr11[key11];
                                {
                                    var a_2 = function f2(a_2, bar_2_1, undefined) {
                                        c = 1 + c, (a_2 && (a_2[(({}, -3) ^ (-1 ^ true)) > (bar_2 && (bar_2[c = 1 + c, (-2 && 1) >= 5 << false >= ((bar_2 && (bar_2[c = 1 + c, 
                                        a_2 && (a_2[b = a] = ((3 || "object") / (bar_2_1 && (bar_2_1[c = 1 + c, a_2 = (-5 >= 1) >> (-3 ^ {}) >>> ("bar" % ([ , 0 ].length === 2) == "c" > 24..toString())] = "function" !== {})), 
                                        (4 == null) < (true != "function")))] ^= "b" & this)) <= (undefined ^ true))] = ([ , 0 ].length === 2) >>> NaN)) / ("foo" & undefined)] += (25 | -5) === 1 % 23..toString())) !== ("function" > 4) + {} % 23..toString();
                                        c = 1 + c, (bar_2 && (bar_2.c = void /[a2][^e]+$/ | -3 ^ 2)) <= (-1 - 25 & ("object" ^ Infinity));
                                    }(1, (c = 1 + c, bar_2 && (bar_2[(c = c + 1) + (a_2 && a_2.undefined)] += ([ , 0 ].length === 2) < Infinity != Infinity - 4 || NaN > "foo" ^ 1 >> 24..toString())));
                                }
                            }
                        }
                        {
                            var expr15 = a++ + new function() {
                                this.NaN = (a_2 && (a_2.c = "" + 5 !== (3 & "b"))) >> (~this == (24..toString() | 22));
                                this.foo += ([] >> Infinity && null == 25) | this >> "c" !== delete [];
                                try {
                                    c = 1 + c, a_2 = "undefined" * 3 < -5 % "undefined" || a_2 && (a_2.null += (23..toString() == -0) >> (5 || 3));
                                } catch (a) {
                                }
                                {
                                    return;
                                    c = 1 + c, (a_2 = -0 << 25 >= ("c" || "number")) & (a_2 += (c = c + 1, 5) / ("" / 4));
                                }
                                L12724: for (var brake19 = 5; (c = 1 + c, ("undefined" >= -1 < 4 % 24..toString()) * ((bar_2 && (bar_2.foo = undefined / 38..toString())) !== ("object" != -1))) && brake19 > 0; --brake19) {
                                    c = 1 + c, (bar_2 && (bar_2[(0 != "function") / (22 !== undefined) % ("" < null && -1 / 23..toString())] += (undefined, 
                                    /[a2][^e]+$/) | undefined < 2)) >= ((3 && -0) !== -1 >>> 38..toString());
                                }
                            }();
                            for (var key15 in expr15) {
                                try {
                                    {
                                        var brake23 = 5;
                                        while (++b && --brake23 > 0) {
                                            var expr24 = (c = 1 + c, (-2 >> 1) - ("undefined" || 1) << (c = c + 1, NaN << 38..toString()));
                                            for (var key24 in expr24) {
                                                c = 1 + c, (-0 || "", 24..toString() - 3) < (undefined == null) >>> (this ^ -1);
                                            }
                                        }
                                    }
                                } catch (Infinity) {
                                    L12725: {
                                    }
                                    L12726: {
                                    }
                                } finally {
                                    {
                                        var brake28 = 5;
                                        do {
                                            c = 1 + c, delete (24..toString() == -3) > (-0 !== "c") << ("function" > -2);
                                        } while ((c = 1 + c, 38..toString() / "c" ^ -4 % -0 || "undefined" > 22 & "a" === -0) && --brake28 > 0);
                                    }
                                    try {
                                        c = 1 + c, a_2 && (a_2.var = ((a_2 && (a_2.var = "" & "foo")) & (a_2 && (a_2[c = 1 + c, 
                                        ("function" < "undefined") * void true / ("" ^ -3 && (c = c + 1, undefined))] &= 4 ^ 4))) >> (undefined << "" >>> [ , 0 ][1] % "foo"));
                                    } finally {
                                    }
                                }
                            }
                        }
                    }();
                }
            }
        }
    }
}

console.log(null, a, b, c, Infinity, NaN, undefined);
```
```js
// uglified code
// (beautified)
for (var _calls_ = 10, a = 100, b = 10, c = 0, a_2 = "function(){}NaN", brake8 = 5; a_2 && 0 < --brake8; ) {
    var expr9 = (c += 1) + {
        0: a_2 && a_2.b,
        c: a++ + a,
        var: (c += 1) + {
            0: a++ + {
                a: --b + a_2,
                "-2": --b + {
                    in: (a_2 = 0, 4 == this || 0),
                    "": !1 | !1 < (1 === this),
                    "": ~((a_2 = 0) <= 2),
                    1.5: !1
                }[c = 1 + (1 + (1 + (1 + (1 + (1 + c))))), 0],
                length: (c += 1) + void 0,
                "": (c += 1) + (c = 1 + c, ("" + (!1 <= (a_2 && (a_2[c = 1 + c, 0 != this <= 0 === 1] *= -20)) !== 0 || 3))[!1 ^ (a_2 /= !0)]),
                a: (c = 1 + ((c = 1 + c) + 1), a_2 = (a_2 && (a_2.var += (a_2 = 0) % -0)) / 3)
            }.foo,
            undefined: (c += 1) + b,
            b: --b + (b + 1 - .3),
            var: {}[a++ + ~((5 == this) % !0 != 0)]
        }[a++ + ("function" == typeof f2 && 0 <= --_calls_ && f2((c += 1) + (b %= a), !0))],
        null: (c += 1) + ("object" != typeof bar_2),
        a: 5
    };
    for (var key9 in expr9) {
        var a_2_1 = function(i) {
            var r = --i;
            for (var n in r) {
                var o = r[n], t = function(r, n) {
                    c = 1 + c, r && (r[(o && (o[c = 1 + c, (o && (o[c = 1 + c, r && (r[i = a] = (n && (n[c = 1 + c, 
                    r = 0] = !0), !0))] ^= "b" & this)) <= 1 <= !1] = 1)) / 0 < 3] += !1), c = 1 + c, 
                    o && (o.c = -1);
                }(1, (c = 1 + (1 + c), o && (o[(c += 1) + (t && t.undefined)] += !0)));
            }
            var _ = a++ + new function() {
                this.NaN = (t && (t.c = !0)) >> (30 == ~this), this.foo += 0 | this >> "c" !== !0;
                try {
                    c = 1 + c, t = t && (t.null += 0);
                } catch (c) {}
            }();
            for (var f in _) {
                try {
                    for (var v = 5; ++i && 0 < --v; ) {
                        for (var b in c = 1 + c, c += 1, 0) {
                            c = 1 + c;
                        }
                    }
                } catch (c) {} finally {
                    c = 1 + (c = 1 + (c = 1 + c)), t && (t.var = ((t && (t.var = 0)) & (t && (t[c = 1 + c, 
                    NaN / void (c += 1)] &= 0))) >> 0);
                }
            }
        }();
    }
}

console.log(null, a, b, c, 1 / 0, NaN, void 0);
```
```
original result:
null 100 10 0 Infinity NaN undefined

uglified result:
null 120 7 896 Infinity NaN undefined
```
```js
// reduced test case (output will differ)

// (beautified)
var a_2 = function f0(a) {
    return a++;
}();

console.log(a_2);
// output: NaN
// 
// minify: undefined
// 
// options: {
//   "compress": {
//     "keep_fargs": false,
//     "passes": 1000000,
//     "sequences": 1000000,
//     "unsafe": true,
//     "unsafe_Function": true,
//     "unsafe_math": true,
//     "unsafe_proto": true,
//     "unsafe_regexp": true
//   }
// }
```
```
minify(options):
{
  "compress": {
    "keep_fargs": false,
    "passes": 1000000,
    "sequences": 1000000,
    "unsafe": true,
    "unsafe_Function": true,
    "unsafe_math": true,
    "unsafe_proto": true,
    "unsafe_regexp": true
  }
}

Suspicious compress options:
  evaluate
  passes
  reduce_vars
  unsafe
  unused
```


Discussion:

Patch:
diff --git a/lib/compress.js b/lib/compress.js
index b82ac81133b..443a6491805 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -3430,7 +3430,7 @@ merge(Compressor.prototype, {
             var v = e._eval(compressor, ignore_side_effects, cached, depth + 1);
             if (v === e) return this;
             modified(e);
-            return v;
+            return +v;
         });
         var non_converting_binary = makePredicate("&& || === !==");
         def(AST_Binary, function(compressor, ignore_side_effects, cached, depth) {


Test patch:
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index a7b5a4a5e33..97b39407cf2 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -2654,3 +2654,18 @@ issue_3933: {
     }
     expect_stdout: "PASS"
 }
+
+issue_3935: {
+    options = {
+        evaluate: true,
+    }
+    input: {
+        console.log(function f(a) {
+            return a++;
+        }());
+    }
+    expect: {
+        console.log(NaN);
+    }
+    expect_stdout: "NaN"
+}