Bug 322769

Summary: Ternary with cast produces different output than else-if
Product: [Eclipse Project] JDT Reporter: David Wright <david.wright>
Component: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: VERIFIED INVALID QA Contact:
Severity: normal    
Priority: P3 CC: Olivier_Thomann, srikanth_sankaran
Version: 3.7   
Target Milestone: 3.7 M2   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description David Wright CLA 2010-08-16 05:52:30 EDT
Build Identifier: Galileo or Helios

/**
<p>Compiled under Helios or Galileo, ternary comes out wrong in one case or the other, depending on value of <code>createIntegers</code>. 
 */
public final class TernaryWithCast{
	private static void testWithFlag(boolean createIntegers){
		System.out.println("createIntegers="+createIntegers);
		double d=0;
		Object ternary,elseIf;
		if(createIntegers)elseIf=new Integer((int)d);
		else elseIf=new Long((long)d);
		ternary=createIntegers?new Integer((int)d):new Long((long)d);
		System.out.println("Integer or Long:" +
				" else if="+elseIf.getClass().getSimpleName()+
				" ternary="+ternary.getClass().getSimpleName());
		if(createIntegers)elseIf=new Integer((int)d);
		else elseIf=new Short((short)d);
		ternary=createIntegers?new Integer((int)d):new Short((short)d);
		System.out.println("Integer or Short" +
				" else if="+elseIf.getClass().getSimpleName()+
				" ternary="+ternary.getClass().getSimpleName());
	}
	public static void main(String[]args){
		boolean createIntegers;
		testWithFlag(createIntegers=false);
		testWithFlag(createIntegers=true);
	}
}


Reproducible: Always

Steps to Reproduce:
1.Compile snippet under Galileo or Helios. 
2.Run and observe output.
4.Optionally, convert ternary using content assist and retest.
Comment 1 Srikanth Sankaran CLA 2010-08-16 06:01:23 EDT
I believe what you are observing is the correct
behavior. See that javac also produces the same
output. I'll dig up the relevant JLS section...
Comment 2 David Wright CLA 2010-08-16 06:15:26 EDT
(In reply to comment #1)
I did wonder, when the output was the same in both Helios and Galileo. Twelve years of coding in Java and I still haven't got to the bottom of it!
Comment 3 Srikanth Sankaran CLA 2010-08-16 06:23:39 EDT
Here is the relevant text from JLS3

15.25 Conditional Operator ? :

...

The type of a conditional expression is determined as follows:

...

Otherwise, if the second and third operands have types that are convertible
(§5.1.8) to numeric types, then there are several cases:

...

Otherwise, binary numeric promotion (§5.6.2) is applied to the operand
types, and the type of the conditional expression is the promoted type of the
second and third operands. Note that binary numeric promotion performs
unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

...

The chosen operand expression is then evaluated and the resulting value is converted
to the type of the conditional expression as determined by the rules stated
above. This conversion may include boxing (§5.1.7) or unboxing conversion. The
operand expression not chosen is not evaluated for that particular evaluation of the
conditional expression.
Comment 4 Olivier Thomann CLA 2010-09-14 10:13:17 EDT
Verified for 3.7M2 using I20100914-0100