diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java index aaf5b8faf132..c3ee81cd2a0f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java @@ -369,7 +369,6 @@ public class TrackingRunner extends StandardDataFlowRunner { Warning caused by narrowing conversion Warning caused by unary minus Warning caused by final field initializer - Literal is not-null TODO: 3. Check how it works with: Inliners (notably: Stream API) Boxed numbers @@ -932,23 +931,25 @@ public class TrackingRunner extends StandardDataFlowRunner { } private static MemoryStateChange findRelationAddedChange(MemoryStateChange history, DfaVariableValue var, Relation relation) { - List subRelations; + List subRelations; switch (relation.myRelationType) { case NE: - subRelations = Arrays.asList(relation, new Relation(RelationType.GT, relation.myCounterpart), - new Relation(RelationType.LT, relation.myCounterpart)); + if (relation.myCounterpart instanceof DfaConstValue) { + return history.findRelation(var, rel -> rel.equals(relation) || + rel.myRelationType == RelationType.EQ && rel.myCounterpart instanceof DfaConstValue, + true); + } + subRelations = Arrays.asList(RelationType.NE, RelationType.GT, RelationType.LT); break; case LE: - subRelations = Arrays.asList(new Relation(RelationType.EQ, relation.myCounterpart), - new Relation(RelationType.LT, relation.myCounterpart)); + subRelations = Arrays.asList(RelationType.EQ, RelationType.LT); break; case GE: - subRelations = Arrays.asList(new Relation(RelationType.EQ, relation.myCounterpart), - new Relation(RelationType.GT, relation.myCounterpart)); + subRelations = Arrays.asList(RelationType.EQ, RelationType.GT); break; default: - subRelations = Collections.singletonList(relation); + subRelations = Collections.singletonList(relation.myRelationType); } - return history.findRelation(var, subRelations::contains, true); + return history.findRelation(var, rel -> rel.myCounterpart == relation.myCounterpart && subRelations.contains(rel.myRelationType), true); } } diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/ConstantStrings.java b/java/java-tests/testData/inspection/dataFlow/tracker/ConstantStrings.java new file mode 100644 index 000000000000..737b053c42a9 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/tracker/ConstantStrings.java @@ -0,0 +1,13 @@ +/* +Value is always false (s == null; line#11) + Result of 's != null' is known from line #10 (!"foo".equals(s) && !"bar".equals(s); line#10) + */ + +import java.util.List; + +class Test { + void test(String s) { + if (!"foo".equals(s) && !"bar".equals(s)) return; + if (s == null) {} + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/ConstantStrings2.java b/java/java-tests/testData/inspection/dataFlow/tracker/ConstantStrings2.java new file mode 100644 index 000000000000..ea347b9175a8 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/tracker/ConstantStrings2.java @@ -0,0 +1,16 @@ +/* +Value is always false (s == null; line#14) + 's' was assigned (=; line#13) + One of the following happens: + Expression cannot be null as it's literal ("foo"; line#13) + or expression cannot be null as it's literal ("bar"; line#13) + */ + +import java.util.List; + +class Test { + void test(boolean b) { + String s = b ? "foo" : "bar"; + if (s == null) {} + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/ListAddContract.java b/java/java-tests/testData/inspection/dataFlow/tracker/ListAddContract.java index e806e8311287..12323a54acc1 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/ListAddContract.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/ListAddContract.java @@ -1,6 +1,6 @@ /* -Value is always true (list.add("foo"); line#9) - According to contract, method 'add' always returns 'true' value (add; line#9) +Value is always true (list.add("foo"); line#10) + According to contract, method 'add' always returns 'true' value (add; line#10) */ import java.util.List; diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java index d1ad493c8627..cc28cef5b933 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java @@ -156,4 +156,6 @@ public class DataFlowInspectionTrackerTest extends LightCodeInsightFixtureTestCa public void testInstanceOfSecondCheck() { doTest(); } public void testNullCheckNpeNullCheck() { doTest(); } public void testListAddContract() { doTest(); } + public void testConstantStrings() { doTest(); } + public void testConstantStrings2() { doTest(); } }