### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java,v retrieving revision 1.60 diff -u -r1.60 AssertStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 7 Mar 2009 01:08:07 -0000 1.60 +++ compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 3 Feb 2010 07:10:33 -0000 @@ -44,8 +44,10 @@ Constant cst = this.assertExpression.optimizedBooleanConstant(); boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true; boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false; - + + flowContext.hideNullComparisonWarnings = true; FlowInfo conditionFlowInfo = this.assertExpression.analyseCode(currentScope, flowContext, flowInfo.copy()); + flowContext.hideNullComparisonWarnings = false; UnconditionalFlowInfo assertWhenTrueInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits(); FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse(); if (isOptimizedTrueAssertion) { Index: compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java,v retrieving revision 1.31 diff -u -r1.31 FinallyFlowContext.java --- compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java 21 Jan 2010 16:48:36 -0000 1.31 +++ compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java 3 Feb 2010 07:10:35 -0000 @@ -96,9 +96,13 @@ case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: if (flowInfo.isDefinitelyNonNull(local)) { if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + } } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + } } continue; } @@ -110,10 +114,14 @@ if (flowInfo.isDefinitelyNull(local)) { switch(this.nullCheckTypes[i] & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + } continue; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + } continue; case FlowContext.IN_ASSIGNMENT: scope.problemReporter().localVariableRedundantNullAssignment(local, expression); @@ -191,10 +199,14 @@ case CAN_ONLY_NULL | IN_INSTANCEOF: if (flowInfo.cannotBeNull(local)) { if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); } else if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) { - scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); } return; @@ -202,11 +214,15 @@ if (flowInfo.canOnlyBeNull(local)) { switch(checkType & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_ASSIGNMENT: @@ -237,10 +253,14 @@ case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: if (flowInfo.isDefinitelyNonNull(local)) { if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); } return; @@ -253,11 +273,15 @@ if (flowInfo.isDefinitelyNull(local)) { switch(checkType & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_ASSIGNMENT: @@ -286,7 +310,13 @@ // never happens } } - recordNullReference(local, reference, checkType); + // if the contention is inside assert statement, we want to avoid null warnings only in case of + // comparisons and not in case of assignment, instanceof, or may be null. + if(!this.hideNullComparisonWarnings || checkType == MAY_NULL + || (checkType & CONTEXT_MASK) == FlowContext.IN_ASSIGNMENT + || (checkType & CONTEXT_MASK) == FlowContext.IN_INSTANCEOF) { + recordNullReference(local, reference, checkType); + } // prepare to re-check with try/catch flow info } } Index: compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java,v retrieving revision 1.62 diff -u -r1.62 FlowContext.java --- compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 21 Jan 2010 16:48:36 -0000 1.62 +++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 3 Feb 2010 07:10:38 -0000 @@ -44,6 +44,10 @@ // any null related operation happening within the try block boolean deferNullDiagnostic, preemptNullDiagnostic; +/** + * used to hide null comparison related warnings inside assert statements + */ +public boolean hideNullComparisonWarnings = false; public static final int CAN_ONLY_NULL_NON_NULL = 0x0000, @@ -542,10 +546,14 @@ case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: if (flowInfo.isDefinitelyNonNull(local)) { if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); } return; @@ -561,11 +569,15 @@ if (flowInfo.isDefinitelyNull(local)) { switch(checkType & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_ASSIGNMENT: Index: compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java,v retrieving revision 1.46 diff -u -r1.46 LoopingFlowContext.java --- compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java 21 Jan 2010 16:48:36 -0000 1.46 +++ compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java 3 Feb 2010 07:10:39 -0000 @@ -127,9 +127,13 @@ if (flowInfo.isDefinitelyNonNull(local)) { this.nullReferences[i] = null; if (this.nullCheckTypes[i] == (CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + } } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + } } continue; } @@ -139,18 +143,26 @@ if (flowInfo.isDefinitelyNonNull(local)) { this.nullReferences[i] = null; if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + } } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + } } continue; } if (flowInfo.isDefinitelyNull(local)) { this.nullReferences[i] = null; if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + } } else { - scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + } } continue; } @@ -163,10 +175,14 @@ this.nullReferences[i] = null; switch(this.nullCheckTypes[i] & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + } continue; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + } continue; case FlowContext.IN_ASSIGNMENT: scope.problemReporter().localVariableRedundantNullAssignment(local, expression); @@ -203,9 +219,13 @@ if (flowInfo.isDefinitelyNonNull(local)) { this.nullReferences[i] = null; if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); + } } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, expression); + } } continue; } @@ -218,10 +238,14 @@ this.nullReferences[i] = null; switch(this.nullCheckTypes[i] & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); + } continue; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, expression); + } continue; case FlowContext.IN_ASSIGNMENT: scope.problemReporter().localVariableRedundantNullAssignment(local, expression); @@ -395,28 +419,40 @@ case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: if (flowInfo.isDefinitelyNonNull(local)) { if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); } else { - scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNonNullComparedToNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); } } else if (flowInfo.isDefinitelyNull(local)) { if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) { - scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); } else { - scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); } } else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local)) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=291418 flowInfo.markAsDefinitelyNonNull(local); - recordNullReference(local, reference, checkType); + if (!this.hideNullComparisonWarnings) { + recordNullReference(local, reference, checkType); + } } else if (! flowInfo.cannotBeDefinitelyNullOrNonNull(local)) { if (flowInfo.isPotentiallyNonNull(local)) { recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & CONTEXT_MASK); } else { - recordNullReference(local, reference, checkType); + if (!this.hideNullComparisonWarnings) { + recordNullReference(local, reference, checkType); + } } } return; @@ -431,11 +467,15 @@ if (flowInfo.isDefinitelyNull(local)) { switch(checkType & CONTEXT_MASK) { case FlowContext.IN_COMPARISON_NULL: - scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableRedundantCheckOnNull(local, reference); + } flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_COMPARISON_NON_NULL: - scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + if (!this.hideNullComparisonWarnings) { + scope.problemReporter().localVariableNullComparedToNonNull(local, reference); + } flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE); return; case FlowContext.IN_ASSIGNMENT: @@ -446,7 +486,13 @@ return; } } - recordNullReference(local, reference, checkType); + // if the contention is inside assert statement, we want to avoid null warnings only in case of + // comparisons and not in case of assignment and instanceof + if (!this.hideNullComparisonWarnings + || (checkType & CONTEXT_MASK) == FlowContext.IN_ASSIGNMENT + || (checkType & CONTEXT_MASK) == FlowContext.IN_INSTANCEOF) { + recordNullReference(local, reference, checkType); + } return; case MAY_NULL : if (flowInfo.isDefinitelyNonNull(local)) { #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java,v retrieving revision 1.85 diff -u -r1.85 NullReferenceTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 21 Jan 2010 17:06:52 -0000 1.85 +++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 3 Feb 2010 07:11:12 -0000 @@ -8156,30 +8156,308 @@ "public class X {\n" + " void foo() {\n" + " Object o = null;\n" + - " assert(o != null);\n" + // complain + " assert(o != null);\n" + // don't complain " if (o == null) { };\n" + // complain " }\n" + "}\n"}, "----------\n" + - "1. ERROR in X.java (at line 4)\n" + - " assert(o != null);\n" + - " ^\n" + - "Null comparison always yields false: The variable o can only be null at this location\n" + - "----------\n" + - "2. ERROR in X.java (at line 5)\n" + + "1. ERROR in X.java (at line 5)\n" + " if (o == null) { };\n" + " ^\n" + "Null comparison always yields false: The variable o cannot be null at this location\n" + "----------\n" + - "3. WARNING in X.java (at line 5)\n" + - " if (o == null) { };\n" + - " ^^^\n" + + "2. WARNING in X.java (at line 5)\n" + + " if (o == null) { };\n" + + " ^^^\n" + + "Dead code\n" + + "----------\n", + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=250056 +// Test to verify that asserts are exempted from null comparison warnings, +// but this doesn't affect the downstream info. +public void test0957_assert() { + if (this.complianceLevel >= ClassFileConstants.JDK1_4) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void m() {\n" + + " X foo = new X();\n" + + " assert (foo != null);\n" + //dont warn + " if (foo == null) {}\n" + + " X foo2 = new X();\n" + + " assert (foo == null);\n" + //dont warn + " if (foo == null) {}\n" + + " X bar = null;\n" + + " assert (bar == null);\n" + //dont warn + " if (bar == null) {}\n" + + " X bar2 = null;\n" + + " assert (bar != null);\n" + //dont warn + " if (bar == null) {}\n" + + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " if (foo == null) {}\n" + + " ^^^\n" + + "Null comparison always yields false: The variable foo cannot be null at this location\n" + + "----------\n" + + "2. WARNING in X.java (at line 5)\n" + + " if (foo == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n" + + "3. ERROR in X.java (at line 8)\n" + + " if (foo == null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable foo can only be null at this location\n" + + "----------\n" + + "4. ERROR in X.java (at line 11)\n" + + " if (bar == null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable bar can only be null at this location\n" + + "----------\n" + + "5. ERROR in X.java (at line 14)\n" + + " if (bar == null) {}\n" + + " ^^^\n" + + "Null comparison always yields false: The variable bar cannot be null at this location\n" + + "----------\n" + + "6. WARNING in X.java (at line 14)\n" + + " if (bar == null) {}\n" + + " ^^\n" + "Dead code\n" + "----------\n", JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); } } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=250056 +// Test to verify that asserts are exempted from null comparison warnings, +// but this doesn't affect the downstream info. +public void test0958_assert() { + if (this.complianceLevel >= ClassFileConstants.JDK1_5) { + this.runNegativeTest( + new String[] { + "X.java", + "import java.util.HashMap;\n" + + "public class X {\n" + + " void m() {\n" + + " HashMap map = new HashMap();\n" + + " X bar = null;\n" + + " X foo = map.get(1);\n" + + " if (foo == null) {\n" + + " foo = new X();\n" + + " map.put(1, foo);\n" + + " }\n" + + " assert (foo != null && bar == null);\n" + // dont warn but do the null analysis + " if (foo != null) {}\n" + // warn + " if (bar == null) {}\n" + // warn + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " if (foo != null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable foo cannot be null at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 13)\n" + + " if (bar == null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable bar can only be null at this location\n" + + "----------\n", + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=250056 +// Test to verify that asserts are exempted from null comparison warnings in a looping context, +// but this doesn't affect the downstream info. +public void test0959a_assert_loop() { + if (this.complianceLevel >= ClassFileConstants.JDK1_4) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void m() {\n" + + " X foo = new X();\n" + + " X foo2 = new X();\n" + + " X bar = null;\n" + + " X bar2 = null;\n" + + " while (true) {\n" + + " assert (foo != null);\n" + //dont warn + " if (foo == null) {}\n" + + " assert (foo2 == null);\n" + //dont warn + " if (foo2 == null) {}\n" + + " assert (bar == null);\n" + //dont warn + " if (bar == null) {}\n" + + " assert (bar2 != null);\n" + //dont warn + " if (bar2 == null) {}\n" + + " }\n" + + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " if (foo == null) {}\n" + + " ^^^\n" + + "Null comparison always yields false: The variable foo cannot be null at this location\n" + + "----------\n" + + "2. WARNING in X.java (at line 9)\n" + + " if (foo == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n" + + "3. ERROR in X.java (at line 11)\n" + + " if (foo2 == null) {}\n" + + " ^^^^\n" + + "Redundant null check: The variable foo2 can only be null at this location\n" + + "----------\n" + + "4. ERROR in X.java (at line 13)\n" + + " if (bar == null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable bar can only be null at this location\n" + + "----------\n" + + "5. ERROR in X.java (at line 15)\n" + + " if (bar2 == null) {}\n" + + " ^^^^\n" + + "Null comparison always yields false: The variable bar2 cannot be null at this location\n" + + "----------\n" + + "6. WARNING in X.java (at line 15)\n" + + " if (bar2 == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n", + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=250056 +// Test to verify that asserts are exempted from null comparison warnings in a looping context, +// but this doesn't affect the downstream info. +public void test0959b_assert_loop() { + if (this.complianceLevel >= ClassFileConstants.JDK1_4) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void m() {\n" + + " while (true) {\n" + + " X foo = new X();\n" + + " assert (foo != null);\n" + //dont warn + " if (foo == null) {}\n" + + " X foo2 = new X();\n" + + " assert (foo2 == null);\n" + //dont warn + " if (foo2 == null) {}\n" + + " X bar = null;\n" + + " assert (bar == null);\n" + //dont warn + " if (bar == null) {}\n" + + " X bar2 = null;\n" + + " assert (bar2 != null);\n" + //dont warn + " if (bar2 == null) {}\n" + + " }\n" + + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " if (foo == null) {}\n" + + " ^^^\n" + + "Null comparison always yields false: The variable foo cannot be null at this location\n" + + "----------\n" + + "2. WARNING in X.java (at line 6)\n" + + " if (foo == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n" + + "3. ERROR in X.java (at line 9)\n" + + " if (foo2 == null) {}\n" + + " ^^^^\n" + + "Redundant null check: The variable foo2 can only be null at this location\n" + + "----------\n" + + "4. ERROR in X.java (at line 12)\n" + + " if (bar == null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable bar can only be null at this location\n" + + "----------\n" + + "5. ERROR in X.java (at line 15)\n" + + " if (bar2 == null) {}\n" + + " ^^^^\n" + + "Null comparison always yields false: The variable bar2 cannot be null at this location\n" + + "----------\n" + + "6. WARNING in X.java (at line 15)\n" + + " if (bar2 == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n", + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=250056 +// Test to verify that asserts are exempted from null comparison warnings in a finally context, +// but this doesn't affect the downstream info. +public void test0960_assert_finally() { + if (this.complianceLevel >= ClassFileConstants.JDK1_4) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void m() {\n" + + " X foo = new X();\n" + + " X foo2 = new X();\n" + + " X bar = null;\n" + + " X bar2 = null;\n" + + " try {\n" + + " System.out.println(\"Inside try\");\n" + + " }\n" + + " finally {\n" + + " assert (foo != null);\n" + //dont warn + " if (foo == null) {}\n" + + " assert (foo2 == null);\n" + //dont warn + " if (foo2 == null) {}\n" + + " assert (bar == null);\n" + //dont warn + " if (bar == null) {}\n" + + " assert (bar2 != null);\n" + //dont warn + " if (bar2 == null) {}\n" + + " }\n" + + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " if (foo == null) {}\n" + + " ^^^\n" + + "Null comparison always yields false: The variable foo cannot be null at this location\n" + + "----------\n" + + "2. WARNING in X.java (at line 12)\n" + + " if (foo == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n" + + "3. ERROR in X.java (at line 14)\n" + + " if (foo2 == null) {}\n" + + " ^^^^\n" + + "Redundant null check: The variable foo2 can only be null at this location\n" + + "----------\n" + + "4. ERROR in X.java (at line 16)\n" + + " if (bar == null) {}\n" + + " ^^^\n" + + "Redundant null check: The variable bar can only be null at this location\n" + + "----------\n" + + "5. ERROR in X.java (at line 18)\n" + + " if (bar2 == null) {}\n" + + " ^^^^\n" + + "Null comparison always yields false: The variable bar2 cannot be null at this location\n" + + "----------\n" + + "6. WARNING in X.java (at line 18)\n" + + " if (bar2 == null) {}\n" + + " ^^\n" + + "Dead code\n" + + "----------\n", + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); + } +} + // null analysis -- notNull protection tag public void _test0900_notNull_protection_tag() { this.runNegativeTest(