Bug 141289

Summary: [1.5][compiler] May need a checkcast when invoking through intersection receiver type
Product: [Eclipse Project] JDT Reporter: Philipe Mulet <philippe_mulet>
Component: CoreAssignee: Philipe Mulet <philippe_mulet>
Status: RESOLVED INVALID QA Contact:
Severity: normal    
Priority: P3    
Version: 3.2   
Target Milestone: 3.3 M3   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Proposed patch none

Description Philipe Mulet CLA 2006-05-11 09:27:43 EDT
3.2RC4

Though the VM tolerates it, it feels like a receiver generic cast is mandated for
the #compareTo(...) invocation (checkcast to Comparable).

public class X {
	public static void main(String[] args) {
		int foo = 0;
		String bar = "zero";
		System.out.println((foo != 0 ? foo : bar).compareTo(null));
	}
}

Currently, the intersection (receiver) type is Object&Comparable<?>&Serializable
it thinks the erasure (Comparable) is good enough. Though since there is no real artifact it relates to, this might be a case where cast is still mandated.
Need to check
Comment 1 Philipe Mulet CLA 2006-10-30 06:02:03 EST
Indeed we produce:
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 3, Locals: 3
  public static void main(String[] args);
     0  iconst_0
     1  istore_1 [foo]
     2  ldc <String "zero"> [16]
     4  astore_2 [bar]
     5  getstatic System.out : PrintStream [18]
     8  iload_1 [foo]
     9  ifeq 19
    12  iload_1 [foo]
    13  invokestatic Integer.valueOf(int) : Integer [24]
    16  goto 20
    19  aload_2 [bar]
    20  aconst_null
    21  invokeinterface Comparable.compareTo(Object) : int [30] [nargs: 2]
    26  invokevirtual PrintStream.println(int) : void [36]
    29  return

where javac 1.6 does:
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 3, Locals: 3
  public static void main(String[] arg0);
     0  iconst_0
     1  istore_1
     2  ldc <String "zero"> [2]
     4  astore_2
     5  getstatic System.out : PrintStream [3]
     8  iload_1
     9  ifeq 19
    12  iload_1
    13  invokestatic Integer.valueOf(int) : Integer [4]
    16  goto 20
    19  aload_2
    20  checkcast Comparable [5]
    23  aconst_null
    24  invokeinterface Comparable.compareTo(Object) : int [6] [nargs: 2]
    29  invokevirtual PrintStream.println(int) : void [7]
    32  return
Comment 2 Philipe Mulet CLA 2006-10-30 06:09:46 EST
Fix for bug 159738 should address this one, but is not enough since intersectionType#erasure() doesn't answer 'Object', but rather 'Comparable<...>' !? Checking the logic.
Comment 3 Philipe Mulet CLA 2006-10-30 06:25:15 EST
Created attachment 52925 [details]
Proposed patch

Fix ensures that intersection type erasures return the first bound, and not the first bound distinct from Object (as it did in the past). This guarantees that fix for bug 159738 performs properly from now on.
Comment 4 Philipe Mulet CLA 2006-10-30 06:48:36 EST
Released for 3.3M3.
Comment 5 Philipe Mulet CLA 2006-10-30 08:56:57 EST
Added GenericTypeTest#test1058
Comment 6 David Audel CLA 2006-10-30 11:56:33 EST
Verified for 3.3 M3 using build I20061030-0010
Comment 7 Philipe Mulet CLA 2006-10-30 17:39:39 EST
Reopening. 

Fix is altering generated bytecodes, and degradating stackmap attributes (see StackMapTableAttributeTest#test008). 
Reverting the change, and added more tests:
GenericTypeTest#test1065-1066, showing that needed casts are present anyway, and that only ClassCastException are issued on negative cases.

Comment 8 Philipe Mulet CLA 2006-10-30 17:40:19 EST
Closing as INVALID.