Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect constructor parameter types when enum resugaring is disabled #383

Open
quat1024 opened this issue Apr 24, 2024 · 1 comment
Open
Labels
Priority: Medium Medium priority regression Used to work before, but doesn't now Subsystem: Writing Anything concerning how expressions are written Type: Bug Something isn't working

Comments

@quat1024
Copy link

quat1024 commented Apr 24, 2024

Vineflower version

vineflower-1.10.1.jar

Describe the bug

My enum:

public enum TestEnum {
	THING1(10f),
	THING2(20f),
	THING3(30f);

	public final float f;
	TestEnum(float f) { this.f = f; }
}

Compiled with Temurin-21.0.3+9.

Decompiled with vineflower-1.10.1.jar --remove-synthetic=false --decompile-enums=false

public final class TestEnum extends Enum<TestEnum> {
   public static final TestEnum THING1 = new TestEnum((float)"THING1", 0, 10.0F);
   public static final TestEnum THING2 = new TestEnum((float)"THING2", 1, 20.0F);
   public static final TestEnum THING3 = new TestEnum((float)"THING3", 2, 30.0F);
   public final float f;
   // $VF: synthetic field
   private static final TestEnum[] $VALUES = $values();

   public static TestEnum[] values() {
      return (TestEnum[])$VALUES.clone();
   }

   public static TestEnum valueOf(String name) {
      return Enum.valueOf(TestEnum.class, name);
   }

   private TestEnum(float param1, int nullx, float f) {
      super(var1, nullx);
      this.f = f;
   }

   // $VF: synthetic method
   private static TestEnum[] $values() {
      return new TestEnum[]{THING1, THING2, THING3};
   }
}
Decompiled with cfr-0.152.jar --sugarenums false
/*
 * Decompiled with CFR 0.152.
 */
public final class TestEnum
extends Enum<TestEnum> {
    public static final /* enum */ TestEnum THING1 = new TestEnum("THING1", 0, 10.0f);
    public static final /* enum */ TestEnum THING2 = new TestEnum("THING2", 1, 20.0f);
    public static final /* enum */ TestEnum THING3 = new TestEnum("THING3", 2, 30.0f);
    public final float f;
    private static final /* synthetic */ TestEnum[] $VALUES;

    public static TestEnum[] values() {
        return (TestEnum[])$VALUES.clone();
    }

    public static TestEnum valueOf(String name) {
        return Enum.valueOf(TestEnum.class, name);
    }

    private TestEnum(String string, int n, float f) {
        super(string, n);
        this.f = f;
    }

    private static /* synthetic */ TestEnum[] $values() {
        return new TestEnum[]{THING1, THING2, THING3};
    }

    static {
        $VALUES = TestEnum.$values();
    }
}
Disassembled with ASM TraceClassAdapter (ASM Bytecode Viewer plugin)
// class version 65.0 (65)
// access flags 0x4031
// signature Ljava/lang/Enum<LTestEnum;>;
// declaration: TestEnum extends java.lang.Enum<TestEnum>
public final enum TestEnum extends java/lang/Enum {

  // compiled from: TestEnum.java

  // access flags 0x4019
  public final static enum LTestEnum; THING1

  // access flags 0x4019
  public final static enum LTestEnum; THING2

  // access flags 0x4019
  public final static enum LTestEnum; THING3

  // access flags 0x11
  public final F f

  // access flags 0x101A
  private final static synthetic [LTestEnum; $VALUES

  // access flags 0x9
  public static values()[LTestEnum;
   L0
    LINENUMBER 1 L0
    GETSTATIC TestEnum.$VALUES : [LTestEnum;
    INVOKEVIRTUAL [LTestEnum;.clone ()Ljava/lang/Object;
    CHECKCAST [LTestEnum;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 0

  // access flags 0x9
  public static valueOf(Ljava/lang/String;)LTestEnum;
    // parameter mandated  <no name>
   L0
    LINENUMBER 1 L0
    LDC LTestEnum;.class
    ALOAD 0
    INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
    CHECKCAST TestEnum
    ARETURN
   L1
    LOCALVARIABLE name Ljava/lang/String; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1

  // access flags 0x2
  // signature (F)V
  // declaration: void <init>(float)
  private <init>(Ljava/lang/String;IF)V
    // parameter synthetic  <no name>
    // parameter synthetic  <no name>
    // parameter  <no name>
   L0
    LINENUMBER 7 L0
    ALOAD 0
    ALOAD 1
    ILOAD 2
    INVOKESPECIAL java/lang/Enum.<init> (Ljava/lang/String;I)V
    ALOAD 0
    FLOAD 3
    PUTFIELD TestEnum.f : F
    RETURN
   L1
    LOCALVARIABLE this LTestEnum; L0 L1 0
    LOCALVARIABLE f F L0 L1 3
    MAXSTACK = 3
    MAXLOCALS = 4

  // access flags 0x100A
  private static synthetic $values()[LTestEnum;
   L0
    LINENUMBER 1 L0
    ICONST_3
    ANEWARRAY TestEnum
    DUP
    ICONST_0
    GETSTATIC TestEnum.THING1 : LTestEnum;
    AASTORE
    DUP
    ICONST_1
    GETSTATIC TestEnum.THING2 : LTestEnum;
    AASTORE
    DUP
    ICONST_2
    GETSTATIC TestEnum.THING3 : LTestEnum;
    AASTORE
    ARETURN
    MAXSTACK = 4
    MAXLOCALS = 0

  // access flags 0x8
  static <clinit>()V
   L0
    LINENUMBER 2 L0
    NEW TestEnum
    DUP
    LDC "THING1"
    ICONST_0
    LDC 10.0
    INVOKESPECIAL TestEnum.<init> (Ljava/lang/String;IF)V
    PUTSTATIC TestEnum.THING1 : LTestEnum;
   L1
    LINENUMBER 3 L1
    NEW TestEnum
    DUP
    LDC "THING2"
    ICONST_1
    LDC 20.0
    INVOKESPECIAL TestEnum.<init> (Ljava/lang/String;IF)V
    PUTSTATIC TestEnum.THING2 : LTestEnum;
   L2
    LINENUMBER 4 L2
    NEW TestEnum
    DUP
    LDC "THING3"
    ICONST_2
    LDC 30.0
    INVOKESPECIAL TestEnum.<init> (Ljava/lang/String;IF)V
    PUTSTATIC TestEnum.THING3 : LTestEnum;
   L3
    LINENUMBER 1 L3
    INVOKESTATIC TestEnum.$values ()[LTestEnum;
    PUTSTATIC TestEnum.$VALUES : [LTestEnum;
    RETURN
    MAXSTACK = 5
    MAXLOCALS = 0
}

Observations:

  • The constructor is decompiled with float as its first argument. In reality, the constructor takes String.
  • The ordinal parameter was given the name nullx.
  • WARN: Inconsistent generic signature in method <init> (Ljava/lang/String;IF)V in TestEnum is printed to the console. This warning does not appear when decompile-enums is enabled.

Additional information

Class file: TestEnum.zip

@quat1024 quat1024 added the Type: Bug Something isn't working label Apr 24, 2024
@quat1024 quat1024 changed the title Incorrect constructor parameter output types when enum resugaring is disabled Incorrect constructor parameter types when enum resugaring is disabled Apr 24, 2024
@jaskarth jaskarth added Subsystem: Writing Anything concerning how expressions are written Priority: Medium Medium priority labels Apr 24, 2024
@jaskarth
Copy link
Member

Did a quick bisection— it last worked in 1.7.0; crashes in 1.8.0 with an IndexOutOfBoundsError; and starts to produce bad code in 1.9.0. nullx shows up as a variable starting with 1.10.0, and as a parameter starting with 1.10.1. I'll do a more thorough bisection when I get a chance.

@jaskarth jaskarth added the regression Used to work before, but doesn't now label Apr 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: Medium Medium priority regression Used to work before, but doesn't now Subsystem: Writing Anything concerning how expressions are written Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants