Repository: mishoo/UglifyJS (JavaScript)

Issue:
ufuzz failure
```js
// original code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;

function f0(a_2, foo_1) {
    let {
        [(c = c + 1) + ((c = c + 1) + (b = a) || a || 3).toString()]: Infinity_2
    } = {
        then: function yield_1() {
            var Infinity_2_1 = b--, Infinity_2_2 = --b + -((5 | 25) <= "undefined" / 24..toString() & ((-42n).toString() != 25) - (Infinity_2_1 && ([ Infinity_2_1.next ] = [ -1 === 38..toString() ])));
        }()
    };
    function f1(Infinity_2_1) {
        {
            var brake2 = 5;
            L21699: do {
            } while ((c = c + 1) + void function() {}() && --brake2 > 0);
        }
    }
    var let_2 = f1(a++ + ({
        c: a_2
    } = a++ + delete (Infinity_2 && (Infinity_2.get += null % -0 >= (25 || undefined)),
    "undefined" < true & (a_2 ||= "bar" << "a")) || {}), "object");
    function f2(await, c_1, let_2) {
        var foo_1 = /[abc4]/.test((foo_1 && foo_1[a++ + {
            NaN: (c = 1 + c, (25 << "undefined" ?? "b" ^ 0) === (-4 + null ^ (foo_1 && (foo_1.null >>>= -3 ?? 0))))
        }.c] || b || 5).toString());
        typeof (1 === 1 ? a : b);
        switch (+((Infinity_2 && (Infinity_2.undefined = "foo" && NaN)) >>> 3 / "function" < (c = c + 1,
        -5 + -4))) {
          case (c = c + 1) + (0 in {
                foo: a_2 && a_2[c = 1 + c, (25 << -0 || "function" ^ "bar") === (38..toString() ^ 24..toString() ^ -0 >= "foo")]
            }):
            (let_2 = null === -1 != null / "object") != 3 * -1 < -1 / "object";
            for (var brake8 = 5; --b + ((c = 1 + c, [] !== "foo" !== false >>> 22 != 23..toString() * ([ , 0 ].length === 2) > (24..toString() & 25)) ? (c = 1 + c,
            (c_1 && (c_1[38..toString() in [ (c = 1 + c, foo_1 && (foo_1[(c = c + 1) + (b = a)] = (-2 + -4) * ("a" ^ "bar") << (1 % /[a2][^e]+$/ !== delete NaN))), (c = 1 + c,
            -3 >= -3 & (c = c + 1, -0) | (-Infinity && (c = c + 1, [ , 0 ][1]))), (c = 1 + c,
            ((c = c + 1, /[a2][^e]+$/) & ([ , 0 ].length === 2) > 2) + (NaN > 1 === ([ , 0 ].length === 2 || /[a2][^e]+$/))) ]] = (4 || "function") - (-2 && 2))) >= (5 < /[a2][^e]+$/) >>> (/[a2][^e]+$/ != -4)) : (c = 1 + c,
            23..toString() == true || null * ([ 3n ][0] > 2), true % "undefined" && 2 !== 0)) && brake8 > 0; --brake8) {}
            try {
                {
                    var expr11 = (c = 1 + c, this % -3 % ("a" ^ "c") >>> ("object" == "function" === ([ , 0 ].length === 2) <= "b"));
                    for (var key11 in expr11) {
                        c = 1 + c;
                        var arguments = expr11[key11];
                        c = 1 + c, (("" & null) != undefined >> -4) * ((foo_1 && (foo_1.b += "b" >= 38..toString())) <= void "c");
                    }
                }
            } finally {}
            break;

          default:
            c = c + 1;

          case let_2 && typeof let_2.Infinity == "function" && --_calls_ >= 0 && ((foo_1 && foo_1[c = 1 + c,
            c = c + 1, 4 * NaN - (c_1 += "undefined" - 3)] || a || 3).toString(),
            let_2.Infinity)():
            {
                var brake14 = 5;
                while (a++ + ((c = 1 + c, (Number(0xdeadn << 16n | 0xbeefn) >= 0 & "" !== []) << (this >> "number") - ("object" <= 0)) ? (c = 1 + c,
                !-5 % (1 != "undefined") ^ void (2 + "object")) : (c = 1 + c, (foo_1 = (2,
                24..toString())) % (0 >= -3) < ([ , 0 ].length === 2 != 22 | (38..toString() && -4)))) && --brake14 > 0) {
                    switch (c = 1 + c, ([ , 0 ][1] ^ Infinity) % ("foo" ?? 24..toString()) || (24..toString() && "a") ^ true * -4) {
                      case c = 1 + c, (-1 << this) - 4 / ([ , 0 ].length === 2) ^ (-4 >> [] ^ ("number" ^ [ , 0 ][1])):
                        ;

                      case c = 1 + c, (4 % "number" && ("c" && "number")) < (foo_1 && (foo_1[!function() {
                        }()] += 38..toString() << /[a2][^e]+$/ > ("a" < 23..toString()))):
                        ;
                        break;

                      case c = 1 + c, foo_1 >>>= 24..toString() - null >>> (Infinity ^ false) >>> ("c" << "function") + (/[a2][^e]+$/ || 22):
                        ;
                        break;

                      case c = 1 + c, ([ , 0 ].length === 2) >= -0 == 2 <= 1 || "a" * "object" === "" >= this:
                        ;
                        break;
                    }
                }
            }
            {
                return --b + (1 === 1 ? a : b);
            }
            break;

          case --b:
            var arguments_2;
            return;
            break;
        }
    }
    var await_1 = f2(-3);
}

var foo_2 = f0(1);

console.log(null, a, b, c, Infinity, NaN, undefined);
```
```js
// uglified code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;

function f0(a_2, foo_1) {
    let {
        [(c += 1) + ((c += 1) + (b = a) || a || 3).toString()]: Infinity_2
    } = {
        then: (Infinity_2_1 = b--, --b, 24..toString(), (-42n).toString(), void (Infinity_2_1 && ([ Infinity_2_1.next ] = [ -1 === 38..toString() ])))
    }, Infinity_2_1;
    (function() {
        for (var brake2 = 5; (c += 1) + void 0 && 0 < --brake2; ) {}
    })((a++, a_2 = (a++ + (Infinity_2 && (Infinity_2.get += !1), a_2 ||= 0, !0) || {})["c"]));
    !function(await, c_1, let_2) {
        var foo_1 = /[abc4]/.test((foo_1 && foo_1[a++ + {
            NaN: (c = 1 + c, 25 == (-4 ^ (foo_1 && (foo_1.null >>>= -3))))
        }.c] || b || 5).toString());
        switch (+((Infinity_2 && (Infinity_2.undefined = NaN)) >>> NaN < -9)) {
          case (c = c + 1 + 1) + (0 in {
                foo: a_2 && a_2[c = 1 + c, 25 == (38..toString() ^ 24..toString() ^ !1)]
            }):
            let_2 = !0;
            for (var brake8 = 5; --b + (c = 1 + c, "foo" !== [] !== 0 != 23..toString() * (2 === [ , 0 ].length) > (25 & 24..toString()) ? (c = 1 + c,
            0 <= (c_1 && (c_1[38..toString() in [ (c = 1 + c, foo_1 && (foo_1[(c += 1) + (b = a)] = -0 << (NaN !== delete NaN))), !0 & -0 | 0, (c = 1 + (c = (c = 1 + c) + 1 + 1),
            c += 1, (/[a2][^e]+$/ & 2 < (2 === [ , 0 ].length)) + (!1 === (2 === [ , 0 ].length || /[a2][^e]+$/))) ]] = 2))) : (c = 1 + c,
            23..toString(), NaN)) && 0 < brake8; --brake8) {}
            c = 1 + c;
            var key11, expr11 = this % -3 % 0 >>> (!1 == (2 === [ , 0 ].length) <= "b");
            for (key11 in expr11) {
                c = 1 + c;
                c = 1 + c, foo_1 && (foo_1.b += 38..toString() <= "b");
            }
            break;

          default:
            c += 1;

          case let_2 && "function" == typeof let_2.Infinity && 0 <= --_calls_ && ((foo_1 && foo_1[c = 1 + c,
            c += 1, NaN - (c_1 += NaN)] || a || 3).toString(), let_2.Infinity)():
            for (var brake14 = 5; a++ + (c = 1 + c, (0 <= Number(0xdeadn << 16n | 0xbeefn) & "" !== []) << (this >> "number") - !1 ? (c = 1 + c,
            0) : (c = 1 + c, (foo_1 = 24..toString()) % !0 < (2 === [ , 0 ].length != 22 | (38..toString() && -4)))) && 0 < --brake14; ) {
                switch (c = 1 + c, -4 ^ (24..toString() && "a")) {
                  case c = 1 + c, (-1 << this) - 4 / (2 === [ , 0 ].length) ^ -4 >> [] ^ 0:
                  case c = 1 + c, NaN < (foo_1 && (foo_1[!0] += 38..toString() << /[a2][^e]+$/ > ("a" < 23..toString()))):
                  case c = 1 + c, foo_1 >>>= 24..toString() - null >>> 0 >>> 0 + /[a2][^e]+$/:
                  case c = 1 + c, -0 <= (2 === [ , 0 ].length) == 0 || NaN === this <= "":
                }
            }
            return --b;

          case --b:
            ;
        }
    }(-3);
}

var foo_2 = f0(1);

console.log(null, a, b, c, 1 / 0, NaN, void 0);
```
```
original result:
null 107 98 36 Infinity NaN undefined

uglified result:
evalmachine.<anonymous>:1
var _calls_=10,a=100,b=10,c=0;function f0(a_2,foo_1){let{[(c+=1)+((c+=1)+(b=a)||a||3).toString()]:Infinity_2}={then:(Infinity_2_1=b--,--b,24..toString(),(-42n).toString(),void(Infinity_2_1&&([Infinity_2_1.next]=[-1===38..toString()])))},Infinity_2_1;(function(){for(var brake2=5;(c+=1)+void 0&&0<--brake2;);})((a++,a_2=(a+++(Infinity_2&&(Infinity_2.get+=!1),a_2||=0,!0)||{})["c"]));!function(await,c_1,let_2){var foo_1=/[abc4]/.test((foo_1&&foo_1[a+++{NaN:(c=1+c,25==(-4^(foo_1&&(foo_1.null>>>=-3))))}.c]||b||5).toString());switch(+((Infinity_2&&(Infinity_2.undefined=NaN))>>>NaN<-9)){case(c=c+1+1)+(0 in{foo:a_2&&a_2[c=1+c,25==(38..toString()^24..toString()^!1)]}):let_2=!0;for(var brake8=5;--b+(c=1+c,"foo"!==[]!==0!=23..toString()*(2===[,0].length)>(25&24..toString())?(c=1+c,0<=(c_1&&(c_1[38..toString()in[(c=1+c,foo_1&&(foo_1[(c+=1)+(b=a)]=-0<<(NaN!==delete NaN))),!0&-0|0,(c=1+(c=(c=1+c)+1+1),c+=1,(/[a2][^e]+$/&2<(2===[,0].length))+(!1===(2===[,0].length||/[a2][^e]+$/)))]]=2))):(c=1+c,23..toString(),NaN))&&0<brake8;--brake8);c=1+c;var key11,expr11=this%-3%0>>>(!1==(2===[,0].length)<="b");for(key11 in expr11){c=1+c;c=1+c,foo_1&&(foo_1.b+=38..toString()<="b")}break;default:c+=1;case let_2&&"function"==typeof let_2.Infinity&&0<=--_calls_&&((foo_1&&foo_1[c=1+c,c+=1,NaN-(c_1+=NaN)]||a||3).toString(),let_2.Infinity)():for(var brake14=5;a+++(c=1+c,(0<=Number(0xdeadn<<16n|0xbeefn)&""!==[])<<(this>>"number")-!1?(c=1+c,0):(c=1+c,(foo_1=24..toString())%!0<(2===[,0].length!=22|(38..toString()&&-4))))&&0<--brake14;)switch(c=1+c,-4^(24..toString()&&"a")){case c=1+c,(-1<<this)-4/(2===[,0].length)^-4>>[]^0:case c=1+c,NaN<(foo_1&&(foo_1[!0]+=38..toString()<</[a2][^e]+$/>("a"<23..toString()))):case c=1+c,foo_1>>>=24..toString()-null>>>0>>>0+/[a2][^e]+$/:case c=1+c,-0<=(2===[,0].length)==0||NaN===this<="":}return--b;case--b:;}}(-3)}var foo_2=f0(1);console.log(null,a,b,c,1/0,NaN,void 0);
                                                                                                                                 ^

ReferenceError: Cannot access 'Infinity_2_1' before initialization
    at f0 (evalmachine.<anonymous>:1:130)
    at evalmachine.<anonymous>:1:1849
    at Script.runInContext (node:vm:141:12)
    at Object.runInContext (node:vm:297:6)
    at run_code_vm (D:\UglifyJS\test\sandbox.js:263:12)
    at exports.run_code (D:\UglifyJS\test\sandbox.js:36:38)
    at run_code (D:\UglifyJS\test\ufuzz\index.js:2122:20)
    at D:\UglifyJS\test\ufuzz\index.js:2578:29
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (D:\UglifyJS\test\ufuzz\index.js:2565:20)
```
```js
// reduced test case (output will differ)

// (beautified)
var b;

function f0() {
    let {
        [0]: Infinity_2
    } = function yield_1() {
        var Infinity_2_1 = b, Infinity_2_2 = 0..log(Infinity_2_1);
    }();
    function f2() {
        switch (Infinity_2) {
          case --b:
        }
    }
}

f0();
// output: TypeError: 0.log is not a function
// minify: ReferenceError: Cannot access 'Infinity_2_1' before initialization
// options: {
//   "mangle": false,
//   "module": false,
//   "output": {
//     "v8": true
//   },
//   "validate": true
// }
```
```
minify(options):
{
  "mangle": false,
  "module": false,
  "output": {
    "v8": true
  }
}

Suspicious compress options:
  inline
  join_vars
  reduce_vars
  unused
```


Discussion:

Patch:
diff --git a/lib/compress.js b/lib/compress.js
index f426cf028d5..494f9db16b4 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -11160,6 +11160,7 @@ Compressor.prototype.compress = function(node) {
         function append_var(decls, expressions, name, value) {
             var def = name.definition();
             if (!scope.var_names().has(name.name)) {
+                if (def.first_decl === name) def.first_decl = null;
                 scope.var_names().set(name.name, true);
                 decls.push(make_node(AST_VarDef, name, {
                     name: name,


Test patch:
diff --git a/test/compress/let.js b/test/compress/let.js
index 69d0d370b6e..7e5185c987c 100644
--- a/test/compress/let.js
+++ b/test/compress/let.js
@@ -2294,3 +2294,37 @@ issue_5591: {
     ]
     node_version: ">=4"
 }
+
+issue_5741: {
+    options = {
+        inline: true,
+        join_vars: true,
+        reduce_vars: true,
+    }
+    input: {
+        "use strict";
+        (function(a) {
+            let b = function() {
+                var c = a;
+                console.log(c);
+            }();
+            function g() {
+                a++;
+                b;
+            }
+        })("PASS");
+    }
+    expect: {
+        "use strict";
+        (function(a) {
+            let b = (c = a, void console.log(c));
+            var c;
+            function g() {
+                a++;
+                b;
+            }
+        })("PASS");
+    }
+    expect_stdout: "PASS"
+    node_version: ">=4"
+}