leibnitz27 / cfr

This is the public repository for the CFR Java decompiler
https://www.benf.org/other/cfr
MIT License
1.94k stars 249 forks source link

Unable to fully structure code on array comparison with ecj #246

Open nbauma109 opened 3 years ago

nbauma109 commented 3 years ago

CFR version

CFR 0.152-SNAPSHOT (bc8d9a2)

Compiler

ecj (tried 2 versions 3.7 and 3.25)

Description

Unable to fully structure code occurs resulting in non-compilable code

Example

This piece of code compares 2 arrays

    public static boolean cmp(int[] a, int[] b) {
        if (a == null) {
           return b == null;
        } else if (b == null) {
           return false;
        } else {
           int i = a.length;
           if (i != b.length) {
              return false;
           } else {
              while(i-- > 0) {
                 if (a[i] != b[i]) {
                    return false;
                 }
              }
              return true;
           }
        }
     }

Result KO with ecj

    /*
     * Unable to fully structure code
     * Enabled aggressive block sorting
     * Lifted jumps to return sites
     */
    public static boolean cmp(int[] var0, int[] var1_1) {
        if (var0 == null) {
            if (var1_1 != null) return false;
            return true;
        }
        if (var1_1 == null) {
            return false;
        }
        var2_2 = var0.length;
        if (var2_2 == var1_1.length) ** GOTO lbl11
        return false;
lbl-1000:
        // 1 sources

        {
            if (var0[var2_2] == var1_1[var2_2]) continue;
            return false;
lbl11:
            // 2 sources

            ** while (var2_2-- > 0)
        }
lbl12:
        // 1 sources

        return true;
    }

Result OK with javac

    public static boolean cmp(int[] arrn, int[] arrn2) {
        if (arrn == null) {
            return arrn2 == null;
        }
        if (arrn2 == null) {
            return false;
        }
        int n = arrn.length;
        if (n != arrn2.length) {
            return false;
        }
        while (n-- > 0) {
            if (arrn[n] == arrn2[n]) continue;
            return false;
        }
        return true;
    }