Community
Participate
Working Groups
The Java 5.0 Compiler of Eclipse 3.1M4 generates bogus code. An example java source file is included below. If compiled by Eclipse 3.1M4 and started as Java application, it throws an error: --- java.lang.VerifyError: (class: Bogon, method: substitutionList signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/util/HashMap;) Incompatible object argument for function call Exception in thread "main" --- If compiled with Sun's compiler (1.5.0_01), it simply prints "Bogon". Apparently the compiler confuses the methods main() and substitutionList(). I think this bug is related to bugs 72528 and 79368. Here is the smallest example I could make to reproduce the problem: (I found that removing any more code fragment removes the bug,too.) --- Begin File: Bogon.java --- import java.util.HashMap; public class Bogon { static HashMap<Character, Character> substitutionList(String s1, String s2) { HashMap<Character, Character> subst = new HashMap<Character, Character>(); for (int i = 0; i < s1.length(); i++) { char key = s1.charAt(i); char value = s2.charAt(i); if (subst.containsKey(key)) { if (value != subst.get(key)) { return null; } } else if (subst.containsValue(value)) { return null; } else { subst.put(key, value); } } return subst; } public static void main(String[] args) { System.out.println("Bogon"); } } --- End File: Bogon.java ---
Offending method code is: // Method descriptor #15 (Ljava/lang/String;Ljava/lang/String;)Ljava/util/HashMap; // Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/util/HashMap<Ljava/lang/Character;Ljava/lang/Character;>; // Stack: 3, Locals: 6 static HashMap substitutionList(String s1, String s2); 0 new #19 java/util/HashMap 3 dup 4 invokespecial #20 <Method java/util/HashMap.<init>()V> 7 astore_2 8 iconst_0 9 istore_3 10 goto 96 13 aload_0 14 iload_3 15 invokevirtual #26 <Method java/lang/String.charAt(I)C> 18 istore 4 20 aload_1 21 iload_3 22 invokevirtual #26 <Method java/lang/String.charAt(I)C> 25 istore 5 27 aload_2 28 iload 4 30 invokestatic #32 <Method java/lang/Character.valueOf(C)Ljava/lang/Character;> 33 invokevirtual #36 <Method java/util/HashMap.containsKey(Ljava/lang/Object;)Z> 36 ifeq 64 39 iload 5 41 aload_2 42 iload 4 44 invokestatic #32 <Method java/lang/Character.valueOf(C)Ljava/lang/Character;> 47 invokevirtual #40 <Method java/util/HashMap.get(Ljava/lang/Object;)Ljava/lang/Object;> 50 checkcast #42 java/lang/Integer 53 invokevirtual #46 <Method java/lang/Character.charValue()C> 56 if_icmpeq 93 59 aconst_null 60 areturn 61 goto 93 64 aload_2 65 iload 5 67 invokestatic #32 <Method java/lang/Character.valueOf(C)Ljava/lang/Character;> 70 invokevirtual #49 <Method java/util/HashMap.containsValue(Ljava/lang/Object;)Z> 73 ifeq 78 76 aconst_null 77 areturn 78 aload_2 79 iload 4 81 invokestatic #32 <Method java/lang/Character.valueOf(C)Ljava/lang/Character;> 84 iload 5 86 invokestatic #32 <Method java/lang/Character.valueOf(C)Ljava/lang/Character;> 89 invokevirtual #53 <Method java/util/HashMap.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;> 92 pop 93 iinc 3 1 96 iload_3 97 aload_0 98 invokevirtual #57 <Method java/lang/String.length()I> 101 if_icmplt 13 104 aload_2 105 areturn Problem is at line: 50 checkcast #42 java/lang/Integer which should rather checkcast Character. Suspecting interference of autoboxing with generic cast.
Problem comes from the fact we use the operator signature to drive the conversion mechanism. Signature is: char2int == char2int --> int. If we changed it to: char2char == char2char --> int, it have the right behavior. But the consequences could be quite severe.
Alternatively, we may instead want to use the compile type instead of runtime one to perform the autoboxing conversion.
Got resolved along with changes which occurred during M5. Added GenericTypeTest#test511. Fix got implemented along the latter suggestion.
I just checked with 3.1M5: The fix works well, thank you! (I was afraid that the fix wouldn't make it into M5. I was proven worng :)
You're welcome, and thx for double checking.