Bug 141289 - [1.5][compiler] May need a checkcast when invoking through intersection receiver type
Summary: [1.5][compiler] May need a checkcast when invoking through intersection recei...
Status: RESOLVED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M3   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-05-11 09:27 EDT by Philipe Mulet CLA
Modified: 2006-10-30 17:40 EST (History)
0 users

See Also:


Attachments
Proposed patch (1.01 KB, patch)
2006-10-30 06:25 EST, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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.