From 4ba13155147ac1e5bee2e203f99f7611dcf99533 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 2 Apr 2019 09:57:25 +0700 Subject: [PATCH] IDEA-210123 BoxedLong.equals(BoxedInteger) is incorrectly reported as 'always true' when their unboxed value is the same --- .../dataFlow/DfaMemoryStateImpl.java | 16 ++++++++++++++++ .../dataFlow/fixture/EqualityLongInteger.java | 10 ++++++++++ .../codeInspection/DataFlowInspectionTest.java | 1 + 3 files changed, 27 insertions(+) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/EqualityLongInteger.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index 6a68e0cd91d8..a6d1df962168 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -1134,6 +1134,13 @@ public class DfaMemoryStateImpl implements DfaMemoryState { dfaRight instanceof DfaVariableValue && !TypeConversionUtil.isPrimitiveWrapper(dfaRight.getType())) { return true; } + PsiType leftType = getPsiType(dfaLeft); + PsiType rightType = getPsiType(dfaRight); + if (TypeConversionUtil.isPrimitiveWrapper(leftType) && + TypeConversionUtil.isPrimitiveWrapper(rightType) && !leftType.equals(rightType)) { + // Boxes of different type (e.g. Long and Integer), cannot be equal even if unboxed values are equal + return negated; + } DfaValue unboxedLeft = SpecialField.UNBOX.createValue(myFactory, dfaLeft); DfaValue unboxedRight = SpecialField.UNBOX.createValue(myFactory, dfaRight); @@ -1149,6 +1156,15 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return applyRelation(unboxedLeft, unboxedRight, negated); } + @Nullable + private static PsiType getPsiType(@NotNull DfaValue value) { + if (value instanceof DfaFactMapValue) { + TypeConstraint constraint = ((DfaFactMapValue)value).get(DfaFactType.TYPE_CONSTRAINT); + return constraint == null ? null : constraint.getPsiType(); + } + return value.getType(); + } + private boolean checkCompareWithBooleanLiteral(DfaValue dfaLeft, DfaValue dfaRight, boolean negated) { if (dfaRight instanceof DfaConstValue) { Object constVal = ((DfaConstValue)dfaRight).getValue(); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EqualityLongInteger.java b/java/java-tests/testData/inspection/dataFlow/fixture/EqualityLongInteger.java new file mode 100644 index 000000000000..9155404b6b65 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/EqualityLongInteger.java @@ -0,0 +1,10 @@ +class Main { + + public static void main(String[] args) { + Integer a = 1; + Integer b = 2; + Long c = 3L; + System.out.println(true); + System.out.println(c.equals(a+b)); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index 95c1dd599a9a..5c6be33e5817 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -661,4 +661,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testInlineSimpleMethods() { doTest(); } public void testInferenceForNonStableParameters() { doTest(); } public void testNullableTernaryInConstructor() { doTest(); } + public void testEqualityLongInteger() { doTest(); } }