diff options
3 files changed, 69 insertions, 6 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java index a4d681957f..b318258f2e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java @@ -52,7 +52,7 @@ public NullAnnotationTest(String name) { // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which do not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "testBug374129" }; +// TESTS_NAMES = new String[] { "testBug385626" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -3652,4 +3652,58 @@ public void testBug374129() { libs, true /* shouldFlush*/); } + +// Bug 385626 - @NonNull fails across loop boundaries +public void testBug385626_1() { + runConformTestWithLibs( + new String[] { + "X.java", + "import java.util.ArrayList;\n" + + "import org.eclipse.jdt.annotation.*;\n" + + "public class X {\n" + + " void test() {\n" + + " for (Integer i : new ArrayList<Integer>()) {\n" + + " if (i != null) {\n" + + " for (Integer j : new ArrayList<Integer>()) {\n" + + " if (j != null) {\n" + + " @NonNull Integer j1 = i; // bogus error was here\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n" + }, + null,//options + ""); +} + +// Bug 385626 - @NonNull fails across loop boundaries +public void testBug385626_2() { + runConformTestWithLibs( + new String[] { + "X.java", + "import java.util.ArrayList;\n" + + "import org.eclipse.jdt.annotation.*;\n" + + "public class X {\n" + + " void test(Integer j) {\n" + + " for (Integer i : new ArrayList<Integer>()) {\n" + + " if (i != null) {\n" + + " try {\n" + + " if (j != null) {\n" + + " @NonNull Integer j1 = i;\n" + + " }\n" + + " } finally {\n" + + " if (j != null) {\n" + + " @NonNull Integer j1 = i; // bogus error was here\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n" + }, + null,//options + ""); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java index 5e7ad1046a..7bbb894d9a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java @@ -12,6 +12,7 @@ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK * bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations + * bug 385626 - @NonNull fails across loop boundaries *******************************************************************************/ package org.eclipse.jdt.internal.compiler.flow; @@ -92,12 +93,16 @@ public void complainOnDeferredChecks(FlowInfo flowInfo, BlockScope scope) { // check inconsistent null checks if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative for (int i = 0; i < this.nullCount; i++) { - if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == ASSIGN_TO_NONNULL) - this.parent.recordNullityMismatch(scope, (Expression)this.nullReferences[i], - this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], flowInfo.nullStatus(this.nullLocals[i])); - else + if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == ASSIGN_TO_NONNULL) { + int nullStatus = flowInfo.nullStatus(this.nullLocals[i]); + if (nullStatus != FlowInfo.NON_NULL) { + this.parent.recordNullityMismatch(scope, (Expression)this.nullReferences[i], + this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus); + } + } else { this.parent.recordUsingNullReference(scope, this.nullLocals[i], this.nullReferences[i], this.nullCheckTypes[i], flowInfo); + } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java index a15b17c2f0..2ac8981e1c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java @@ -13,6 +13,7 @@ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK * bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations + * bug 385626 - @NonNull fails across loop boundaries *******************************************************************************/ package org.eclipse.jdt.internal.compiler.flow; @@ -251,7 +252,10 @@ public void complainOnDeferredNullChecks(BlockScope scope, FlowInfo callerFlowIn } break; case ASSIGN_TO_NONNULL: - this.parent.recordNullityMismatch(scope, (Expression)location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], flowInfo.nullStatus(local)); + int nullStatus = flowInfo.nullStatus(local); + if (nullStatus != FlowInfo.NON_NULL) { + this.parent.recordNullityMismatch(scope, (Expression)location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus); + } break; case EXIT_RESOURCE: FakedTrackingVariable trackingVar = local.closeTracker; |