leibnitz27 / cfr

This is the public repository for the CFR Java decompiler

Home Page:https://www.benf.org/other/cfr

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CFR incorrectly decompiles stack values being reordered

NeRdTheNed opened this issue · comments

CFR version

CFR 0.152 / CFR 0.153-SNAPSHOT (d6f6758)

Compiler

Jasmin / generated bytecode

Description

This example conditionally changes the order of the current 3 values on the stack, swapping the first and last values. In the decompiled output when bl is false, the values of n6 and n4 are not swapped properly, as it instead overwrites n4 with the value of n6 only. I noticed this when generating JVM bytecode for a project, I'm unsure if the Java compiler would output something like this naturally. This bug report is based on a report I wrote up for QuiltFlower (Vineflower/vineflower#216), which also has a similar issue when decompiling this .class file.

Example

Jasmin example code:

.class public com/example/Bug
.super java/lang/Object

.method private <init>()V
	aload_0
	invokespecial java/lang/Object/<init>()V
	return
.end method

.method public static bugDemo(IIIZ)I
	.limit stack 4
	.limit locals 4

	iload_0
	iconst_2
	imul

	iload_1
	iconst_2
	imul

	iload_2
	iconst_2
	imul

    ; Swap order of values on stack conditionally
	iload_3
	ifne Target

    ; Order is changed from 0, 1, 2 to 2, 1, 0
	dup_x2
	pop
	swap

Target:

	ineg
	iadd
	iadd
	ireturn
.end method

...and the compiled .class file. And here's the decompiled output (output is the same on CFR 0.153-SNAPSHOT (d6f6758)):

/*
 * Decompiled with CFR 0.152.
 */
package com.example;

public class Bug {
    private Bug() {
    }

    public static int bugDemo(int n, int n2, int n3, boolean bl) {
        int n4 = n * 2;
        int n5 = n2 * 2;
        int n6 = n3 * 2;
        if (!bl) {
            n4 = n6;
            n6 = n4;
            n5 = n5;
        }
        return n4 + (n5 + -n6);
    }
}