Bug 83860 - [1.5] java.lang.VerifyError with Enums
Summary: [1.5] java.lang.VerifyError with Enums
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 critical (vote)
Target Milestone: 3.1 M5   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-27 14:23 EST by Matthew Hall CLA
Modified: 2005-02-16 12:35 EST (History)
0 users

See Also:


Attachments
Apply on CodeStream (742 bytes, patch)
2005-01-27 15:45 EST, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Hall CLA 2005-01-27 14:23:10 EST
The following test case fails when compiled in eclipse, but passes when compiled
with the Sun JDK.

Tested against integration build 3.1_I20050126-0800.

---- EnumTest.java ----

import junit.framework.TestCase;

public class EnumTest extends TestCase {
  /* 
   * MyEnum has a non-null, private constructor, and ITEM is an anonymous
   * subclass.  These three factors together cause a VerifyError to be thrown.
   * Omit any one factor and the test passes.
   */
  enum MyEnum {
    ITEM (0) {}; // curly braces make ITEM an anonymous subclass

    private MyEnum(int i) {}
  }

  public void testMyEnum() {
    try {
      MyEnum.values();
    } catch (VerifyError ve) {
      fail();
    }
  }

  /* 
   * MyEnumNoAnonymousSubclass has a non-null, private constructor.  No
   * VerifyError occurs.
   */
  enum MyEnumNoAnonymousSubclass {
    ITEM (0);

    private MyEnumNoAnonymousSubclass(int i) {}
  }

  public void testMyEnumNoAnonymousSubclass() {
    try {
      MyEnumNoAnonymousSubclass.values();
    } catch (VerifyError ve) {
      fail();
    }
  }

  /*
   * MyEnumNonPrivateConstructor has a non-null constructor, and ITEM is an
   * anonymous subclass.  No VerifyError occurs.
   */
  enum MyEnumNonPrivateConstructor {
    ITEM (0) {};

    MyEnumNonPrivateConstructor(int i) {}
  }

  public void testMyEnumNonPrivateConstructor() {
    try {
      MyEnumNonPrivateConstructor.values();
    } catch (VerifyError ve) {
      fail();
    }
  }

  /*
   * MyEnumNullConstructor has a private constructor, and ITEM is an anonymous
   * subclass.  No VerifyError occurs.
   */
  enum MyEnumNullConstructor {
    ITEM () {};

    private MyEnumNullConstructor() {}
  }

  public void testMyEnumNullConstructor() {
    try {
      MyEnumNullConstructor.values();
    } catch (VerifyError ve) {
      fail();
    }
  }
}
Comment 1 Olivier Thomann CLA 2005-01-27 14:29:08 EST
I will investigate.
Comment 2 Olivier Thomann CLA 2005-01-27 14:44:40 EST
Reproduced.
Exception in thread "main" java.lang.VerifyError: (class: X, method: <init>
signature: (Ljava/lang/String;IILX;)V) Register 1 contains wrong type

Test case is:
enum X {
    ITEM (0) {}; // curly braces make ITEM an anonymous subclass

    private X(int i) {}
    
    public static void main(String[] args) {
    	for (X x : values()) {
    		System.out.println(x);
    	}
    }
}
The line:
    3  iload_1 is boggus. It should be:
    3  iload_3

  // Method descriptor  #73 (Ljava/lang/String;IILX;)V
  // Stack: 4, Locals: 5
  synthetic X(String arg, int arg, int arg, X arg);
    0  aload_0 [local_0]
    1  aload_1 [local_1]
    2  iload_2 [local_2]
    3  iload_1 [local_1]
    4  invokespecial X.<init>(Ljava/lang/String;II)V [74]
    7  return
      Line numbers:
        [pc: 0, line: 4]
Comment 3 Olivier Thomann CLA 2005-01-27 15:45:20 EST
Created attachment 17526 [details]
Apply on CodeStream
Comment 4 Philipe Mulet CLA 2005-01-27 15:57:36 EST
Patch looks good. I would write it though:

if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) {
	this.aload_1(); // pass along name param as name arg
	this.iload_2(); // pass along ordinal param as ordinal arg
	resolvedPosition += 2;
}	
Comment 5 Olivier Thomann CLA 2005-01-27 16:53:49 EST
Fixed and released in HEAD.
Regression test added in EnumTest.test066.
Comment 6 David Audel CLA 2005-02-16 12:35:40 EST
Verified in I20050215-2300