### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java,v retrieving revision 1.117 diff -u -r1.117 SingleNameReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 7 Apr 2010 12:47:50 -0000 1.117 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java 15 Jul 2010 16:33:42 -0000 @@ -77,10 +77,14 @@ currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); // we could improve error msg here telling "cannot use compound assignment on final local variable" } - if (isReachable) { - localBinding.useFlag = LocalVariableBinding.USED; - } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { - localBinding.useFlag = LocalVariableBinding.FAKE_USED; + if (localBinding.useFlag != LocalVariableBinding.USED) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318571 + // access from compound assignment does not prevent "unused" warning, unless unboxing is involved: + if (isReachable && (this.implicitConversion & TypeIds.UNBOXING) != 0) { + localBinding.useFlag = LocalVariableBinding.USED; + } else { + localBinding.useFlag = LocalVariableBinding.FAKE_USED; + } } } } @@ -461,6 +465,14 @@ * are optimized in one access: e.g "a = a + 1" optimized into "a++". */ public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { + if (!valueRequired && ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL)) { + LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; + if (localBinding.useFlag == LocalVariableBinding.FAKE_USED) { + // report the case of a local variable that is unread except for this compound assignment + currentScope.problemReporter().unusedLocalVariable(localBinding.declaration); + localBinding.useFlag = LocalVariableBinding.USED; // don't report again + } + } this.generateCompoundAssignment( currentScope, codeStream, @@ -661,6 +673,15 @@ return; case Binding.LOCAL : // assigning to a local variable LocalVariableBinding localBinding = (LocalVariableBinding) this.binding; + + if (!valueRequired) { + if (localBinding.useFlag == LocalVariableBinding.FAKE_USED) { + // report the case of a local variable that is unread except for postIncrement expressions + currentScope.problemReporter().unusedLocalVariable(localBinding.declaration); + localBinding.useFlag = LocalVariableBinding.USED; // don't report again + } + } + // using incr bytecode if possible if (localBinding.type == TypeBinding.INT) { if (valueRequired) { #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java,v retrieving revision 1.23 diff -u -r1.23 ProgrammingProblemsTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java 14 Jul 2010 10:37:24 -0000 1.23 +++ src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java 15 Jul 2010 16:33:49 -0000 @@ -1683,4 +1683,42 @@ "The assignment to variable nvx has no effect\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682 +public void test0046() { + if (this.complianceLevel < ClassFileConstants.JDK1_5) + return; + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING); + this.runNegativeTest( + new String[] { + "X.java", + "class X {\n" + + " int foo() {\n" + + " int i=1;\n" + + " boolean b=false;\n" + + " b|=true;\n" + // not a relevant usage + " int k = 2;\n" + + " --k;\n" + // not a relevant usage + " k+=3;\n" + // not a relevant usage + " Integer j = 3;\n" + + " j++;\n" + // relevant because unboxing is involved + " return i++;\n" + // value after increment is used + " }\n" + + "}" + }, + "----------\n" + + "1. WARNING in X.java (at line 4)\n" + + " boolean b=false;\n" + + " ^\n" + + "The local variable b is never read\n" + + "----------\n" + + "2. WARNING in X.java (at line 6)\n" + + " int k = 2;\n" + + " ^\n" + + "The local variable k is never read\n" + + "----------\n", + null/*classLibraries*/, + true/*shouldFlushOutputDirectory*/, + customOptions); +} } \ No newline at end of file