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 70a717094153..d3cafdb282c3 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 @@ -1382,26 +1382,18 @@ public class TrackingRunner extends DataFlowRunner { } private static MemoryStateChange findRelationAddedChange(MemoryStateChange history, DfaVariableValue var, Relation relation) { - List subRelations; - switch (relation.myRelationType) { - case NE: - if (relation.myCounterpart.getDfType() instanceof DfConstantType) { - return history.findRelation(var, rel -> rel.equals(relation) || - rel.myRelationType == RelationType.EQ && - rel.myCounterpart.getDfType() instanceof DfConstantType, - true); - } - subRelations = Arrays.asList(RelationType.NE, RelationType.GT, RelationType.LT); - break; - case LE: - subRelations = Arrays.asList(RelationType.EQ, RelationType.LT); - break; - case GE: - subRelations = Arrays.asList(RelationType.EQ, RelationType.GT); - break; - default: - subRelations = Collections.singletonList(relation.myRelationType); + if (relation.myRelationType == RelationType.NE && relation.myCounterpart.getDfType() instanceof DfConstantType) { + return history.findRelation(var, rel -> rel.equals(relation) || + rel.myRelationType == RelationType.EQ && + rel.myCounterpart.getDfType() instanceof DfConstantType, + true); } - return history.findRelation(var, rel -> rel.myCounterpart == relation.myCounterpart && subRelations.contains(rel.myRelationType), true); + MemoryStateChange exact = history.findRelation(var, rel -> rel.myCounterpart == relation.myCounterpart && + relation.myRelationType.equals(rel.myRelationType), true); + if (exact != null) { + return exact; + } + return history.findRelation(var, rel -> rel.myCounterpart == relation.myCounterpart && + relation.myRelationType.isSubRelation(rel.myRelationType), true); } } diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/EqualsLessEquals.java b/java/java-tests/testData/inspection/dataFlow/tracker/EqualsLessEquals.java new file mode 100644 index 000000000000..10ab25dcc1a6 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/tracker/EqualsLessEquals.java @@ -0,0 +1,19 @@ +/* +Value is always false (i == expected; line#15) + Condition 'i != expected' was checked before (i == expected; line#9) + */ +class A + void compareInts(int i) { + int expected = new Random().nextInt(100); + int result; + if (i == expected) { + result = 0; + } + else if (i < expected) { + result = -1; + } + else if (i == expected) { + result = 0; + } + } +} \ No newline at end of file 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 605cb63764ae..95b712558920 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java @@ -182,4 +182,5 @@ public class DataFlowInspectionTrackerTest extends LightJavaCodeInsightFixtureTe public void testMergeOnAnd() { doTest(); } public void testPassedNotNull() { doTest(); } public void testClassCheckInStream() { doTest(); } + public void testEqualsLessEquals() { doTest(); } }