Bug 115693

Summary: [1.5][compiler] Unnecessary double checkcast instruction emmited
Product: [Eclipse Project] JDT Reporter: dpr
Component: CoreAssignee: Philipe Mulet <philippe_mulet>
Status: VERIFIED FIXED QA Contact:
Severity: minor    
Priority: P3 CC: frederic_fusier, mlists
Version: 3.2   
Target Milestone: 3.2 M4   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Test project
none
Correct bytecode
none
Incorrect bytecode with double checkcast none

Description dpr CLA 2005-11-09 15:27:10 EST
Just spotted a minor bytecode generation error. I'll try to attach a simple test
project. When this project is built after clean everithing is ok. But when class
D is recompiled incrementally a double checkcast instruction is emmited.
Comment 1 dpr CLA 2005-11-09 15:28:18 EST
Created attachment 29635 [details]
Test project
Comment 2 dpr CLA 2005-11-09 15:29:15 EST
Created attachment 29636 [details]
Correct bytecode
Comment 3 dpr CLA 2005-11-09 15:30:07 EST
Created attachment 29637 [details]
Incorrect bytecode with double checkcast
Comment 4 Philipe Mulet CLA 2005-12-05 06:51:32 EST
Good find, indeed the cast is overkill after the generic cast conversion.
Fixed in latest. Added GenericTypeTest#test874.
No plan to backport to 3.1.2 since really not severe.

Fixed
Comment 5 Frederic Fusier CLA 2005-12-13 09:54:00 EST
Verified for 3.2 M4 using build I20051213-0010
Comment 6 Frederic Fusier CLA 2005-12-13 14:45:14 EST
In fact, GenericTypeTests#test874 already passes with M3. So, it seems that the problem is fixed but we currently need to investigate in order to know precisely which changes has done it
=> reopen until clarified...
Comment 7 Frederic Fusier CLA 2005-12-13 14:46:01 EST
Note also that test passes with 3.1.2 (ie. there's only one checkcast)
Comment 8 Philipe Mulet CLA 2005-12-13 14:52:37 EST
It feels like this regression got introduced after M3; and given it isn't in 3.1.2, it would point at the unification of generic and parameterized bindings.

Need to understand what exactly occurred there; i.e. is fix really needed, or is it working around another issue ?
Comment 9 Philipe Mulet CLA 2005-12-14 15:03:37 EST
The original testcase didn't fail in 3.1.2&3.2M3, since the return type is generic type (instead of parameterized type - pre binding unification); consequently, no generic cast is inserted as generic type interestingly doesn't have its tagbits saying HasTypeVariable true (!?).

In 3.2, it works as expected.

Here is another testcase which would fail in 3.1.2&3.2M3:

class A {}
class D extends A {}
abstract class B<T> {
    public T label(String s) { return null; }
}
final class C extends B<A> {
    public static C instance(String s) { return new C(); }
    @Override public String toString() {
    	return "SUCCESS"; 
    }
}
public class X {
    public static void main(String[] args) {
        D d = (D)C.instance("X").label("Y");
        System.out.println(d);
    }
}

It would issue a double checkcast D inside X#main().
Added GenericTypeTest#test878
Comment 10 Philipe Mulet CLA 2005-12-14 15:25:16 EST
Fixed buildnotes (re-inserted), and tagged for M4.
Frederic - pls verify it.
Comment 11 Olivier Thomann CLA 2005-12-14 19:52:15 EST
Verified in build I20051214-1600.

output is:

  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 2, Locals: 2
  public static void main(java.lang.String[] args);
     0  ldc <String "X"> [16]
     2  invokestatic C.instance(java.lang.String) : C [17]
     5  ldc <String "Y"> [23]
     7  invokevirtual C.label(java.lang.String) : java.lang.Object [25]
    10  checkcast D [29]
    13  astore_1 [d]
    14  getstatic java.lang.System.out : java.io.PrintStream [31]
    17  aload_1 [d]
    18  invokevirtual java.io.PrintStream.println(java.lang.Object) : void [37]
    21  return