Community
Participate
Working Groups
There is a bug in binary compatibility of enum 'switch tables' generated by the Eclipse compiler. This bug probably applies to all Eclipse compiler versions supporting Java enums. The following sample code is used to demonstrate the problem: enum Action { ONE, TWO }; class Test { public static void main(String[] args) { for(Action a : Action.values()) { switch(a) { case ONE: System.out.println("one"); break; case TWO: System.out.println("two"); break; default: System.out.println("unknown action "+ a); } } } } The output of running above Test class is: one two When an Action enum will evolve, for example to the following one: enum Action { ONE, TWO, THREE }; The result of running Test class (without recompiling) will be: one two one Instead of expected: one two unknown action THREE Decompiled version of a Test class explains it in details: // Decompiled by DJ v3.8.8.85 Copyright 2005 Atanas Neshkov Date: 2006-05-15 18:39:57 // Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version! // Decompiler options: packimports(3) deadcode nonlb space // Source File Name: Test.java import java.io.PrintStream; // Referenced classes of package : // Action public class Test { public Test() { } public static void main(String args[]) { Action aaction[] = Action.values(); int i = 0; for (int j = aaction.length; i < j; i++) { Action a = aaction[i]; switch ($SWITCH_TABLE$Action()[a.ordinal()]) { case 0: // '\0' System.out.println("one"); break; case 1: // '\001' System.out.println("two"); break; default: System.out.println((new StringBuilder("unknown action ")).append(a).toString()); break; } } } static int[] $SWITCH_TABLE$Action() { $SWITCH_TABLE$Action; if ($SWITCH_TABLE$Action == null) goto _L2; else goto _L1 _L1: return; _L2: JVM INSTR pop ; int ai[] = new int[Action.values().length]; try { ai[Action.ONE.ordinal()] = 0; } catch (NoSuchFieldError _ex) { } try { ai[Action.TWO.ordinal()] = 1; } catch (NoSuchFieldError _ex) { } return $SWITCH_TABLE$Action = ai; } private static int $SWITCH_TABLE$Action[]; } One of the simplest ways to fix that is to add Arrays.fill(ai, -1), after 'ai' table creation in the above code. The same will be achieved without adding additional processing using 1 (instead of 0) as a starting ordinal index for known enum constants references in the above like code generation (this is the way chosen by the Sun Java compiler). Regards, piotr
I'll look at it.
We either fill the array with -1 or we never use the value 0 as a return value through the X.$SWITCH_TABLE$Action() call. Philippe, This is quite easy to fix. I'll prepare a fix for tomorrow. This will give me the time to run all the tests. Piotr, nice catch and thanks for the nice test case.
I have a fix. I'll do more testing before I post it.
Created attachment 41544 [details] Regression test
Created attachment 41547 [details] Proposed fix This patch doesn't use 0 as a possible value in the SWITCH_TABLE array.
All existing tests passed.
Fix looks good. +1 for 3.2.1
Fixed and released in branch 3.2.1. Regression test added in org.eclipse.jdt.core.tests.compiler.regression.EnumTest.test130
Released for 3.2.1 Released for 3.3 M1 while merging TARGET_321 in HEAD
Verified for 3.3 M1 using build I20060807-2000.
Verified for 3.2.1 using build M20060908-1655