Storyyeller / Krakatau

Java decompiler, assembler, and disassembler
GNU General Public License v3.0
1.95k stars 220 forks source link

Incorrect code through interface casting #75

Closed samczsun closed 8 years ago

samczsun commented 8 years ago
.method public static main : ([Ljava/lang/String;)V 
    .code stack 10 locals 10 
        .catch java/lang/Throwable from L0 to L1 using L2
        iconst_1
        anewarray java/io/Serializable
        astore_0
        aload_0
        iconst_0
        new java/lang/Exception
        dup
        invokespecial Method java/lang/Exception <init> ()V
        aastore
        aload_0
        iconst_0
        aaload
L0:
        checkcast java/lang/Exception
L1:
        astore_0
        aconst_null
L2:
        getstatic java/lang/System out Ljava/io/PrintStream;
        aload_0
        invokevirtual Method java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end code 
.end method 

Decompiled:

    public static void main(String[] a)
    {
        java.io.Serializable[] a0 = new java.io.Serializable[1];
        a0[0] = (java.io.Serializable)(Object)new Exception();
        java.io.Serializable a1 = a0[0];
        try
        {
            Exception a2 = (Exception)(Object)a1;
            a0 = null;
        }
        catch(ClassCastException ignoredException)
        {
        }
        System.out.println((Object)a0);
    }

Output:

java.lang.Exception

Removing the astore_0 after L1 or changing the array type to java/lang/Exception will fix it

Storyyeller commented 8 years ago

I think this is the same issue as #74 except in reverse. The problem is that the optimizer's type system doesn't handle interfaces, so it treats Exception and Serializeable as independent classes and hence assumes the cast will always fail.

samczsun commented 8 years ago

Sounds good. I'll close this one and leave the other one be