Bug 88395

Summary: [1.5][compiler] Binary compat problem with enum/switch codegen
Product: [Eclipse Project] JDT Reporter: Tim Hanson <thanson>
Component: CoreAssignee: Olivier Thomann <Olivier_Thomann>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: mlists
Version: 3.1   
Target Milestone: 3.1 RC1   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Apply on HEAD
none
Apply on HEAD of org.eclipse.jdt.core.tests.compiler
none
Apply on HEAD
none
Apply on HEAD
none
Apply on HEAD of org.eclipse.jdt.core.tests.compiler none

Description Tim Hanson CLA 2005-03-17 17:30:58 EST
Compile the following two files:

Color.java:
----------------------
package pack;
enum Color {WHITE, BLACK}
----------------------

Test.java:
package pack;
import static pack.Color.*;

public class Test {
    public static void main(String[] args) {
        Color c = BLACK;
        switch(c) {
        case BLACK:
            System.out.println("Black");
            break;
        case WHITE:
            System.out.println("White");
            break;
        }
    }

}
-----------------------------------------

Execute pack.Test and it will print out:
Black
as expected.

Now reorder the two constants inside Color.java and recompile ONLY Color.java.
Now execute pack.Test and it will print out:
White

This violates 13.4.26 of JLS V3

The problem is that the generated switch depends on the ordinal value from the
enum. javac creates a translation table from compile time ordinal-> run time
ordinal and switches based on the translated value.
Comment 1 Olivier Thomann CLA 2005-05-20 15:03:58 EDT
Created attachment 21522 [details]
Apply on HEAD
Comment 2 Olivier Thomann CLA 2005-05-20 15:06:43 EDT
Created attachment 21523 [details]
Apply on HEAD of  org.eclipse.jdt.core.tests.compiler

Corresponding regression tests. I will add more.
Comment 3 Olivier Thomann CLA 2005-05-20 15:12:51 EDT
I just found a bug in my patch when I have two switchs for the same enum type. I
create the synthetic field twice. I am investigating.
Comment 4 Olivier Thomann CLA 2005-05-20 15:30:07 EDT
Created attachment 21527 [details]
Apply on HEAD
Comment 5 Olivier Thomann CLA 2005-05-20 15:33:08 EDT
Created attachment 21528 [details]
Apply on HEAD

Remove HashMap from SwitchStatement to replace it with a SyntheticMethodBinding
field. A switch statement can only have one synthetic method. So there is no
need for a hash map.
Comment 6 Olivier Thomann CLA 2005-05-20 15:34:01 EDT
Created attachment 21529 [details]
Apply on HEAD of  org.eclipse.jdt.core.tests.compiler

More tests.
Comment 7 Olivier Thomann CLA 2005-05-20 16:02:57 EDT
Fixed and released in HEAD.
Regression tests in
org.eclipse.jdt.core.tests.compiler.regression.EnumTest.test105-111.

Changes in:
org.eclipse.jdt.internal.compiler.ClassFile
org.eclipse.jdt.internal.compiler.ast.SwitchStatement
org.eclipse.jdt.internal.compiler.codegen.CodeStream
org.eclipse.jdt.internal.compiler.codegen.ConstantPool
org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding
org.eclipse.jdt.internal.compiler.lookup.TypeConstants
Comment 8 Frederic Fusier CLA 2005-05-27 04:47:10 EDT
Verified for 3.1 RC1 with build I20050527-0010.