Bug 78008 - [1.5][compiler] java.lang.VerifyError on shortcut if-else
Summary: [1.5][compiler] java.lang.VerifyError on shortcut if-else
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.1 M4   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 80605 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-11-05 20:42 EST by Jens Elkner CLA
Modified: 2004-12-14 14:51 EST (History)
1 user (show)

See Also:


Attachments
Apply on HEAD (1.07 KB, patch)
2004-11-06 10:22 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 Jens Elkner CLA 2004-11-05 20:42:07 EST
Env: eclipse-gtk-3.1M3 linux

JDT seems unable to handle the following short-cut if-else statement:

public class ShortcutIfElse {

    public ShortcutIfElse() { }
	
    public Integer[] getTypes() {
        List<Integer> list = new ArrayList<Integer>();
        return list == null 
            ? new Integer[0] 
            : list.toArray(new Integer[list.size()]);
    }

    public static void main(String[] args) {
        Class clazz = null;
        try {
            clazz = Class.forName("ShortcutIfElse");
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

Exception in thread "main" java.lang.VerifyError: (class: ShortcutIfElse,
method: getTypes signature: ()[Ljava/lang/Integer;) Wrong return type in function
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:164)
...
Comment 1 Olivier Thomann CLA 2004-11-06 10:04:44 EST
We miss a checkcast after the toArray() call.

We generate:
    29  invokeinterface [nargs : 2] #30 <Interface method
java/util/List.toArray([Ljava/lang/Object;)[Ljava/lang/Object;>
    34  areturn

instead of:

    29  invokeinterface [nargs : 2] #6 <Interface method
java/util/List.toArray([Ljava/lang/Object;)[Ljava/lang/Object;>
    34  checkcast #7 [Ljava/lang/Integer;
    37 areturn





Comment 2 Olivier Thomann CLA 2004-11-06 10:06:34 EST
java.util.List.toArray(...) signature is:
<T> T[] toArray(T[] a)

So we should implicitely generate a cast to T[].
Comment 3 Olivier Thomann CLA 2004-11-06 10:22:47 EST
Created attachment 15711 [details]
Apply on HEAD

This is a case where we optimized the implicit conversion of the false part.
Doing this we didn't set the genericCast field and therefore there is no cast
generated after the invokeinterface.
Comment 4 Olivier Thomann CLA 2004-11-06 10:24:20 EST
A workaround is to reverse the condition.

        return list != null 
            ? list.toArray(new Integer[list.size()])
            : new Integer[0] ;

works fine without the patch.
Comment 5 Philipe Mulet CLA 2004-11-10 06:22:19 EST
Patch looks good. We are also missing #computeConversion calls further down in case:

if (scope.environment().options.sourceLevel >= ClassFileConstants.JDK1_5) {
Comment 6 Philipe Mulet CLA 2004-11-10 06:34:05 EST
Added regression test: GenericTypeTest#test408.
Fixed
Comment 7 Philipe Mulet CLA 2004-11-10 06:59:18 EST
Also added #test409 for other case mentionned in previous comment, corresponding
to scenario:

import java.util.*;
public class X {

    public Number getTypes() {
        List<Integer> list = new ArrayList<Integer>();
        return list == null 
            ? Float.valueOf(0) 
            : list.get(0);
    }

    public static void main(String[] args) {
        Class clazz = null;
        try {
            clazz = Class.forName("X");
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
Comment 8 Olivier Thomann CLA 2004-12-09 11:49:23 EST
*** Bug 80605 has been marked as a duplicate of this bug. ***
Comment 9 Olivier Thomann CLA 2004-12-14 14:51:33 EST
Verified in 200412140800