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

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java (-47 lines)
Lines 2374-2426 Link Here
2374
			"SUCCESS"
2374
			"SUCCESS"
2375
		);
2375
		);
2376
}
2376
}
2377
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=359284
2378
// Verify that needless checkcast is not emitted.
2379
public void test062() throws Exception {
2380
	String source =
2381
		"public class X {\n" +
2382
	    "public X() {\n" +
2383
	    "    Object[] x = null;\n" +
2384
	    "}\n" +
2385
	    "}\n";
2386
		this.runConformTest(
2387
				new String[] {
2388
					"X.java",
2389
					source
2390
				},
2391
				""
2392
			);
2393
		String expectedOutput = 
2394
				"public class X {\n" + 
2395
				"  \n" + 
2396
				"  // Method descriptor #6 ()V\n" + 
2397
				"  // Stack: 1, Locals: 2\n" + 
2398
				"  public X();\n" + 
2399
				"    0  aload_0 [this]\n" + 
2400
				"    1  invokespecial java.lang.Object() [8]\n" + 
2401
				"    4  aconst_null\n" + 
2402
				"    5  astore_1 [x]\n" + 
2403
				"    6  return\n" + 
2404
				"      Line numbers:\n" + 
2405
				"        [pc: 0, line: 2]\n" + 
2406
				"        [pc: 4, line: 3]\n" + 
2407
				"        [pc: 6, line: 4]\n" + 
2408
				"      Local variable table:\n" + 
2409
				"        [pc: 0, pc: 7] local: this index: 0 type: X\n" + 
2410
				"        [pc: 6, pc: 7] local: x index: 1 type: java.lang.Object[]\n" + 
2411
				"}";
2412
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
2413
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
2414
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
2415
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
2416
		int index = result.indexOf(expectedOutput);
2417
		if (index == -1 || expectedOutput.length() == 0) {
2418
			System.out.println(Util.displayString(result, 3));
2419
		}
2420
		if (index == -1) {
2421
			assertEquals("Wrong contents", expectedOutput, result);
2422
		}
2423
}
2424
public static Class testClass() {
2377
public static Class testClass() {
2425
	return CastTest.class;
2378
	return CastTest.class;
2426
}
2379
}
(-)a/org.eclipse.jdt.core/buildnotes_jdt-core.html (-3 / +1 lines)
Lines 246-254 Link Here
246
</li>
246
</li>
247
</ul>
247
</ul>
248
<h3>Problem Reports Fixed</h3>
248
<h3>Problem Reports Fixed</h3>
249
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359284">359284</a>
249
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a>
250
Unnecessary checkast from null
251
<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a>
252
invokedynamic in generated class file is not correctly recognized by the eclipse compiler
250
invokedynamic in generated class file is not correctly recognized by the eclipse compiler
253
<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360644">360644</a>
251
<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360644">360644</a>
254
Scope.isDefinedInSameUnit(ReferenceBinding) fails for a ParameterizedTypeBinding
252
Scope.isDefinedInSameUnit(ReferenceBinding) fails for a ParameterizedTypeBinding
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java (+20 lines)
Lines 53-58 Link Here
53
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
53
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
54
	int pc = codeStream.position;
54
	int pc = codeStream.position;
55
	this.receiver.generateCode(currentScope, codeStream, true);
55
	this.receiver.generateCode(currentScope, codeStream, true);
56
	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
57
			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
58
		codeStream.checkcast(this.receiver.resolvedType);
59
	}
56
	codeStream.recordPositionsFrom(pc, this.sourceStart);
60
	codeStream.recordPositionsFrom(pc, this.sourceStart);
57
	this.position.generateCode(currentScope, codeStream, true);
61
	this.position.generateCode(currentScope, codeStream, true);
58
	assignment.expression.generateCode(currentScope, codeStream, true);
62
	assignment.expression.generateCode(currentScope, codeStream, true);
Lines 68-73 Link Here
68
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
72
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
69
	int pc = codeStream.position;
73
	int pc = codeStream.position;
70
	this.receiver.generateCode(currentScope, codeStream, true);
74
	this.receiver.generateCode(currentScope, codeStream, true);
75
	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
76
			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
77
		codeStream.checkcast(this.receiver.resolvedType);
78
	}
71
	this.position.generateCode(currentScope, codeStream, true);
79
	this.position.generateCode(currentScope, codeStream, true);
72
	codeStream.arrayAt(this.resolvedType.id);
80
	codeStream.arrayAt(this.resolvedType.id);
73
	// Generating code for the potential runtime type checking
81
	// Generating code for the potential runtime type checking
Lines 91-96 Link Here
91
99
92
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
100
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
93
	this.receiver.generateCode(currentScope, codeStream, true);
101
	this.receiver.generateCode(currentScope, codeStream, true);
102
	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
103
			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
104
		codeStream.checkcast(this.receiver.resolvedType);
105
	}
94
	this.position.generateCode(currentScope, codeStream, true);
106
	this.position.generateCode(currentScope, codeStream, true);
95
	codeStream.dup2();
107
	codeStream.dup2();
96
	codeStream.arrayAt(this.resolvedType.id);
108
	codeStream.arrayAt(this.resolvedType.id);
Lines 120-125 Link Here
120
132
121
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
133
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
122
	this.receiver.generateCode(currentScope, codeStream, true);
134
	this.receiver.generateCode(currentScope, codeStream, true);
135
	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
136
			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
137
		codeStream.checkcast(this.receiver.resolvedType);
138
	}
123
	this.position.generateCode(currentScope, codeStream, true);
139
	this.position.generateCode(currentScope, codeStream, true);
124
	codeStream.dup2();
140
	codeStream.dup2();
125
	codeStream.arrayAt(this.resolvedType.id);
141
	codeStream.arrayAt(this.resolvedType.id);
Lines 155-160 Link Here
155
171
156
public TypeBinding resolveType(BlockScope scope) {
172
public TypeBinding resolveType(BlockScope scope) {
157
	this.constant = Constant.NotAConstant;
173
	this.constant = Constant.NotAConstant;
174
	if (this.receiver instanceof CastExpression	// no cast check for ((type[])null)[0]
175
			&& ((CastExpression)this.receiver).innermostCastedExpression() instanceof NullLiteral) {
176
		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
177
	}
158
	TypeBinding arrayType = this.receiver.resolveType(scope);
178
	TypeBinding arrayType = this.receiver.resolveType(scope);
159
	if (arrayType != null) {
179
	if (arrayType != null) {
160
		this.receiver.computeConversion(scope, arrayType, arrayType);
180
		this.receiver.computeConversion(scope, arrayType, arrayType);
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (+7 lines)
Lines 133-138 Link Here
133
				break generateInit;
133
				break generateInit;
134
			}
134
			}
135
			this.initialization.generateCode(currentScope, codeStream, true);
135
			this.initialization.generateCode(currentScope, codeStream, true);
136
			// 26903, need extra cast to store null in array local var
137
			if (this.binding.type.isArrayType()
138
				&& (this.initialization.resolvedType == TypeBinding.NULL	// arrayLoc = null
139
					|| ((this.initialization instanceof CastExpression)	// arrayLoc = (type[])null
140
						&& (((CastExpression)this.initialization).innermostCastedExpression().resolvedType == TypeBinding.NULL)))){
141
				codeStream.checkcast(this.binding.type);
142
			}
136
			codeStream.store(this.binding, false);
143
			codeStream.store(this.binding, false);
137
			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) {
144
			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) {
138
				/* Variable may have been initialized during the code initializing it
145
				/* Variable may have been initialized during the code initializing it
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (+8 lines)
Lines 350-355 Link Here
350
				}
350
				}
351
				return;
351
				return;
352
			}
352
			}
353
			// 26903, need extra cast to store null in array local var
354
			if (localBinding.type.isArrayType()
355
				&& (assignment.expression.resolvedType == TypeBinding.NULL	// arrayLoc = null
356
					|| ((assignment.expression instanceof CastExpression)	// arrayLoc = (type[])null
357
						&& (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == TypeBinding.NULL)))){
358
				codeStream.checkcast(localBinding.type);
359
			}
360
353
			// normal local assignment (since cannot store in outer local which are final locations)
361
			// normal local assignment (since cannot store in outer local which are final locations)
354
			codeStream.store(localBinding, valueRequired);
362
			codeStream.store(localBinding, valueRequired);
355
			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) { // for local variable debug attributes
363
			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) { // for local variable debug attributes

Return to bug 359284