View | Details | Raw Unified | Return to bug 287676 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java (+42 lines)
Lines 1744-1749 Link Here
1744
		"",
1744
		"",
1745
		JavacTestOptions.SKIP);
1745
		JavacTestOptions.SKIP);
1746
}
1746
}
1747
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=287676
1748
// Test to make sure that an unnecessary cast warning is produced in case of
1749
// wrapper types like Integer, Character, Short, Byte, etc.
1750
public void test047() {
1751
	CompilerOptions options = new CompilerOptions(getCompilerOptions());
1752
	if(options.sourceLevel >= ClassFileConstants.JDK1_5){
1753
		String expectedOutput = 
1754
				"----------\n" +
1755
				"1. WARNING in X.java (at line 5)\n" +
1756
				"	a = (Integer)a + (Integer)2;\n" +
1757
				"	    ^^^^^^^^^^\n" +
1758
				"Unnecessary cast from Integer to Integer\n" +
1759
				"----------\n" +
1760
				"2. WARNING in X.java (at line 5)\n" +
1761
				"	a = (Integer)a + (Integer)2;\n" +
1762
				"	                 ^^^^^^^^^^\n" +
1763
				"Unnecessary cast from int to Integer\n" +
1764
				"----------\n" +
1765
				"3. WARNING in X.java (at line 6)\n" +
1766
				"	if ((Character)aList.get(0) == 'c')\n" +
1767
				"	    ^^^^^^^^^^^^^^^^^^^^^^^\n" +
1768
				"Unnecessary cast from Character to Character\n" +
1769
				"----------\n";
1770
1771
1772
		this.runNegativeTest(
1773
				new String[] {
1774
						"X.java",
1775
						"import java.util.ArrayList;\n" +
1776
						"public class X{\n" +
1777
						"	void test() {" +
1778
						"		Integer a = 1;\n" +
1779
						"		ArrayList<Character> aList = new ArrayList<Character>(1);\n" +
1780
						"		a = (Integer)a + (Integer)2;\n" +
1781
						"		if ((Character)aList.get(0) == 'c')\n" +
1782
						"			System.out.println();\n" +
1783
						"	}\n" +
1784
						"}\n"
1785
				},
1786
				expectedOutput);
1787
	}
1788
}
1747
public static Class testClass() {
1789
public static Class testClass() {
1748
	return CastTest.class;
1790
	return CastTest.class;
1749
}
1791
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java (-4 / +6 lines)
Lines 192-205 Link Here
192
192
193
	// check need for left operand cast
193
	// check need for left operand cast
194
	int alternateLeftTypeId = leftTypeId;
194
	int alternateLeftTypeId = leftTypeId;
195
	boolean unnecessaryLeftCast = (left.bits & ASTNode.UnnecessaryCast) != 0;
196
	boolean unnecessaryRightCast = (right.bits & ASTNode.UnnecessaryCast) != 0;
195
	if (leftIsCast) {
197
	if (leftIsCast) {
196
		if ((left.bits & ASTNode.UnnecessaryCast) == 0 && left.resolvedType.isBaseType()) {
198
		if (!unnecessaryLeftCast && left.resolvedType.isBaseType()) {
197
			// narrowing conversion on base type may change value, thus necessary
199
			// narrowing conversion on base type may change value, thus necessary
198
			leftIsCast = false;
200
			leftIsCast = false;
199
		} else  {
201
		} else  {
200
			TypeBinding alternateLeftType = ((CastExpression)left).expression.resolvedType;
202
			TypeBinding alternateLeftType = ((CastExpression)left).expression.resolvedType;
201
			if (alternateLeftType == null) return; // cannot do better
203
			if (alternateLeftType == null) return; // cannot do better
202
			if ((alternateLeftTypeId = alternateLeftType.id) == leftTypeId) { // obvious identity cast
204
			if ((alternateLeftTypeId = alternateLeftType.id) == leftTypeId || scope.environment().computeBoxingType(alternateLeftType).id == leftTypeId) { // obvious identity cast
203
				scope.problemReporter().unnecessaryCast((CastExpression)left);
205
				scope.problemReporter().unnecessaryCast((CastExpression)left);
204
				leftIsCast = false;
206
				leftIsCast = false;
205
			} else if (alternateLeftTypeId == TypeIds.T_null) {
207
			} else if (alternateLeftTypeId == TypeIds.T_null) {
Lines 211-223 Link Here
211
	// check need for right operand cast
213
	// check need for right operand cast
212
	int alternateRightTypeId = rightTypeId;
214
	int alternateRightTypeId = rightTypeId;
213
	if (rightIsCast) {
215
	if (rightIsCast) {
214
		if ((right.bits & ASTNode.UnnecessaryCast) == 0 && right.resolvedType.isBaseType()) {
216
		if (!unnecessaryRightCast && right.resolvedType.isBaseType()) {
215
			// narrowing conversion on base type may change value, thus necessary
217
			// narrowing conversion on base type may change value, thus necessary
216
			rightIsCast = false;
218
			rightIsCast = false;
217
		} else {
219
		} else {
218
			TypeBinding alternateRightType = ((CastExpression)right).expression.resolvedType;
220
			TypeBinding alternateRightType = ((CastExpression)right).expression.resolvedType;
219
			if (alternateRightType == null) return; // cannot do better
221
			if (alternateRightType == null) return; // cannot do better
220
			if ((alternateRightTypeId = alternateRightType.id) == rightTypeId) { // obvious identity cast
222
			if ((alternateRightTypeId = alternateRightType.id) == rightTypeId || scope.environment().computeBoxingType(alternateRightType).id == rightTypeId) { // obvious identity cast
221
				scope.problemReporter().unnecessaryCast((CastExpression)right);
223
				scope.problemReporter().unnecessaryCast((CastExpression)right);
222
				rightIsCast = false;
224
				rightIsCast = false;
223
			} else if (alternateRightTypeId == TypeIds.T_null) {
225
			} else if (alternateRightTypeId == TypeIds.T_null) {

Return to bug 287676