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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java (+4 lines)
Lines 194-199 Link Here
194
					System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
194
					System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
195
					classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC);
195
					classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC);
196
				}
196
				}
197
			} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
198
				classFile.contentsOffset = problemResetPC;
199
				classFile.methodCount--;
200
				this.generateCode(classFile); // restart method generation
197
			} else {
201
			} else {
198
				// produce a problem method accounting for this fatal error
202
				// produce a problem method accounting for this fatal error
199
				int problemsLength;
203
				int problemsLength;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java (+4 lines)
Lines 123-128 Link Here
123
					classFile.contentsOffset = clinitOffset;
123
					classFile.contentsOffset = clinitOffset;
124
					classFile.methodCount--;
124
					classFile.methodCount--;
125
				}
125
				}
126
			} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
127
				classFile.contentsOffset = clinitOffset;
128
				classFile.methodCount--;
129
				this.generateCode(classFile); // restart method generation
126
			} else {
130
			} else {
127
				// produce a problem method accounting for this fatal error
131
				// produce a problem method accounting for this fatal error
128
				classFile.contentsOffset = clinitOffset;
132
				classFile.contentsOffset = clinitOffset;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java (+4 lines)
Lines 228-233 Link Here
228
				System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
228
				System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
229
				classFile.addProblemConstructor(this, this.binding, problemsCopy, problemResetPC);
229
				classFile.addProblemConstructor(this, this.binding, problemsCopy, problemResetPC);
230
			}
230
			}
231
		} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
232
			classFile.contentsOffset = problemResetPC;
233
			classFile.methodCount--;
234
			this.generateCode(classFile); // restart method generation
231
		} else {
235
		} else {
232
			int problemsLength;
236
			int problemsLength;
233
			CategorizedProblem[] problems =
237
			CategorizedProblem[] problems =
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (+26 lines)
Lines 39-44 Link Here
39
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
39
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
40
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
40
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
41
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
41
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
42
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
42
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
43
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
43
44
44
public class SingleNameReference extends NameReference implements OperatorIds {
45
public class SingleNameReference extends NameReference implements OperatorIds {
Lines 422-427 Link Here
422
				break;
423
				break;
423
			case Binding.LOCAL : // reading a local
424
			case Binding.LOCAL : // reading a local
424
				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
425
				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
426
				if (localBinding.resolvedPosition == -1) {
427
					if (valueRequired) {
428
						// restart code gen
429
						localBinding.useFlag = LocalVariableBinding.USED;
430
						throw new AbortMethod(currentScope.referenceCompilationUnit().compilationResult, null);
431
					}
432
					codeStream.recordPositionsFrom(pc, this.sourceStart);
433
					return;
434
				}
425
				if (!valueRequired && (this.implicitConversion & TypeIds.UNBOXING) == 0) {
435
				if (!valueRequired && (this.implicitConversion & TypeIds.UNBOXING) == 0) {
426
					// if no valueRequired, optimize out entire gen
436
					// if no valueRequired, optimize out entire gen
427
					codeStream.recordPositionsFrom(pc, this.sourceStart);
437
					codeStream.recordPositionsFrom(pc, this.sourceStart);
Lines 525-530 Link Here
525
		case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
535
		case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
526
			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
536
			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
527
			// using incr bytecode if possible
537
			// using incr bytecode if possible
538
			if (localBinding.resolvedPosition == -1) {
539
				if (valueRequired) {
540
					// restart code gen
541
					localBinding.useFlag = LocalVariableBinding.USED;
542
					throw new AbortMethod(currentScope.referenceCompilationUnit().compilationResult, null);
543
				}
544
				return;
545
			}
528
			switch (localBinding.type.id) {
546
			switch (localBinding.type.id) {
529
				case T_JavaLangString :
547
				case T_JavaLangString :
530
					codeStream.generateStringConcatenationAppend(currentScope, this, expression);
548
					codeStream.generateStringConcatenationAppend(currentScope, this, expression);
Lines 687-692 Link Here
687
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
705
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
688
			// check if postIncrement is the only usage of this local
706
			// check if postIncrement is the only usage of this local
689
			Reference.reportOnlyUselesslyReadLocal(currentScope, localBinding, valueRequired);
707
			Reference.reportOnlyUselesslyReadLocal(currentScope, localBinding, valueRequired);
708
			if (localBinding.resolvedPosition == -1) {
709
				if (valueRequired) {
710
					// restart code gen
711
					localBinding.useFlag = LocalVariableBinding.USED;
712
					throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
713
				}
714
				return;
715
			}
690
716
691
			// using incr bytecode if possible
717
			// using incr bytecode if possible
692
			if (localBinding.type == TypeBinding.INT) {
718
			if (localBinding.type == TypeBinding.INT) {
(-)compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java (-1 / +2 lines)
Lines 41-47 Link Here
41
	static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
41
	static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
42
	static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
42
	static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
43
	public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
43
	public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
44
	
44
	public static final CompilationResult RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE = new CompilationResult((char[])null, 0, 0, 0);
45
45
	public int allLocalsCounter;
46
	public int allLocalsCounter;
46
	public byte[] bCodeStream;
47
	public byte[] bCodeStream;
47
	public ClassFile classFile; // The current classfile it is associated to.
48
	public ClassFile classFile; // The current classfile it is associated to.
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (-1 / +1 lines)
Lines 191-197 Link Here
191
			LocalVariableBinding local = this.locals[ilocal]; // if no local at all, will be locals[ilocal]==null
191
			LocalVariableBinding local = this.locals[ilocal]; // if no local at all, will be locals[ilocal]==null
192
192
193
			// check if variable is actually used, and may force it to be preserved
193
			// check if variable is actually used, and may force it to be preserved
194
			boolean generateCurrentLocalVar = (local.useFlag != LocalVariableBinding.UNUSED && local.constant() == Constant.NotAConstant);
194
			boolean generateCurrentLocalVar = (local.useFlag > LocalVariableBinding.UNUSED && local.constant() == Constant.NotAConstant);
195
195
196
			// do not report fake used variable
196
			// do not report fake used variable
197
			if (local.useFlag == LocalVariableBinding.UNUSED
197
			if (local.useFlag == LocalVariableBinding.UNUSED
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java (+18 lines)
Lines 38-43 Link Here
38
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
38
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
39
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
39
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
40
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
40
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
41
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
41
42
42
/**
43
/**
43
 * A single name reference inside a code snippet can denote a field of a remote
44
 * A single name reference inside a code snippet can denote a field of a remote
Lines 270-275 Link Here
270
				break;
271
				break;
271
			case Binding.LOCAL : // reading a local
272
			case Binding.LOCAL : // reading a local
272
				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
273
				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
274
				if (localBinding.resolvedPosition == -1) {
275
					if (valueRequired) {
276
						// restart code gen
277
						localBinding.useFlag = LocalVariableBinding.USED;
278
						throw new AbortMethod(currentScope.referenceCompilationUnit().compilationResult, null);
279
					}
280
					codeStream.recordPositionsFrom(pc, this.sourceStart);
281
					return;
282
				}
273
				if (!valueRequired)
283
				if (!valueRequired)
274
					break;
284
					break;
275
				// outer local?
285
				// outer local?
Lines 340-345 Link Here
340
			break;
350
			break;
341
		case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
351
		case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
342
			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
352
			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
353
			if (localBinding.resolvedPosition == -1) {
354
				if (valueRequired) {
355
					// restart code gen
356
					localBinding.useFlag = LocalVariableBinding.USED;
357
					throw new AbortMethod(currentScope.referenceCompilationUnit().compilationResult, null);
358
				}
359
				return;
360
			}
343
			// using incr bytecode if possible
361
			// using incr bytecode if possible
344
			switch (localBinding.type.id) {
362
			switch (localBinding.type.id) {
345
				case T_JavaLangString :
363
				case T_JavaLangString :
(-)src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java (-3 / +78 lines)
Lines 11-16 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.jdt.core.tests.compiler.regression;
12
package org.eclipse.jdt.core.tests.compiler.regression;
13
13
14
import java.io.File;
14
import java.util.HashMap;
15
import java.util.HashMap;
15
import java.util.Map;
16
import java.util.Map;
16
17
Lines 36-42 Link Here
36
  	// -Dcompliance=1.4 (for example) to lower it if needed
37
  	// -Dcompliance=1.4 (for example) to lower it if needed
37
  	static {
38
  	static {
38
//    	TESTS_NAMES = new String[] { "test001" };
39
//    	TESTS_NAMES = new String[] { "test001" };
39
//		TESTS_NUMBERS = new int[] { 43 };
40
//		TESTS_NUMBERS = new int[] { 53 };
40
//  	TESTS_RANGE = new int[] { 1, -1 };
41
//  	TESTS_RANGE = new int[] { 1, -1 };
41
  	}
42
  	}
42
43
Lines 47-53 Link Here
47
public static Class testClass() {
48
public static Class testClass() {
48
    return ProgrammingProblemsTest.class;
49
    return ProgrammingProblemsTest.class;
49
}
50
}
50
51
protected Map getCompilerOptions() {
52
	Map compilerOptions = super.getCompilerOptions();
53
	compilerOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal,  CompilerOptions.OPTIMIZE_OUT);
54
	return compilerOptions;
55
}
51
void runTest(
56
void runTest(
52
		String[] testFiles,
57
		String[] testFiles,
53
		String[] errorOptions,
58
		String[] errorOptions,
Lines 2120-2124 Link Here
2120
			true/*shouldFlushOutputDirectory*/,
2125
			true/*shouldFlushOutputDirectory*/,
2121
			customOptions);
2126
			customOptions);
2122
}
2127
}
2123
2128
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
2129
//To verify that unused local warning is not shown for locals declared in unreachable code
2130
public void test0052() throws Exception {
2131
	Map customOptions = getCompilerOptions();
2132
	customOptions.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.ERROR);
2133
	this.runConformTest(
2134
		new String[] {
2135
			"X.java",
2136
			"class X {\n" + 
2137
			"    int foo() {\n" + 
2138
			"        int i=1;\n" +
2139
			"        return i++;\n" + 	// value is used as it is returned
2140
			"    }\n" + 
2141
			"}"
2142
		},
2143
		"",
2144
		null/*classLibraries*/,
2145
		true/*shouldFlushOutputDirectory*/,
2146
		null,
2147
		customOptions,
2148
		null);
2149
	String expectedOutput =
2150
		"  // Method descriptor #15 ()I\n" + 
2151
		"  // Stack: 1, Locals: 2\n" + 
2152
		"  int foo();\n" + 
2153
		"    0  iconst_1\n" + 
2154
		"    1  istore_1 [i]\n" + 
2155
		"    2  iload_1 [i]\n" + 
2156
		"    3  iinc 1 1 [i]\n" + 
2157
		"    6  ireturn\n" + 
2158
		"      Line numbers:\n" + 
2159
		"        [pc: 0, line: 3]\n" + 
2160
		"        [pc: 2, line: 4]\n" + 
2161
		"      Local variable table:\n" + 
2162
		"        [pc: 0, pc: 7] local: this index: 0 type: X\n" + 
2163
		"        [pc: 2, pc: 7] local: i index: 1 type: int\n";
2164
	checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
2165
}
2166
//To verify that unused local warning is not shown for locals declared in unreachable code
2167
public void test0053() throws Exception {
2168
	Map customOptions = getCompilerOptions();
2169
	customOptions.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING);
2170
	this.runConformTest(
2171
		new String[] {
2172
			"X.java",
2173
			"class X {\n" + 
2174
			"    int foo() {\n" + 
2175
			"        int i=1;\n" +
2176
			"        i++;\n" + 	// value after increment is still not used
2177
			"        return 0;\n" + 
2178
			"    }\n" + 
2179
			"}"
2180
		},
2181
		"",
2182
		null/*classLibraries*/,
2183
		true/*shouldFlushOutputDirectory*/,
2184
		null,
2185
		customOptions,
2186
		null);
2187
	String expectedOutput =
2188
		"  // Method descriptor #15 ()I\n" + 
2189
		"  // Stack: 1, Locals: 1\n" + 
2190
		"  int foo();\n" + 
2191
		"    0  iconst_0\n" + 
2192
		"    1  ireturn\n" + 
2193
		"      Line numbers:\n" + 
2194
		"        [pc: 0, line: 5]\n" + 
2195
		"      Local variable table:\n" + 
2196
		"        [pc: 0, pc: 2] local: this index: 0 type: X\n";
2197
	checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
2198
}
2124
}
2199
}

Return to bug 328519