From 8466dca99392dcfacaa2a39b3910a72891c8875a Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 25 Mar 2021 11:47:16 +0700 Subject: [PATCH] [java-dfa] containsConstant should ignore locality if values are compared by equals Fixes IDEA-265089 ConstantCondition always false incorrectly reported on String.equals with String literal on left side GitOrigin-RevId: 4e128a8308a9813bba953e107400c51879a6e7f2 --- .../dataFlow/types/DfReferenceType.java | 6 +++++- .../StringEqualityNewStringInMethod.java | 18 ++++++++++++++++++ .../codeInspection/DataFlowInspectionTest.java | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/StringEqualityNewStringInMethod.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfReferenceType.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfReferenceType.java index 44f1d13e934c..97750b0da05d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfReferenceType.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/types/DfReferenceType.java @@ -125,7 +125,11 @@ public interface DfReferenceType extends DfType { @Override default boolean containsConstant(@NotNull DfConstantType constant) { - return dropTypeConstraint().isSuperType(constant); + DfReferenceType filtered = dropTypeConstraint(); + if (getConstraint().isComparedByEquals()) { + filtered = filtered.dropLocality(); + } + return filtered.isSuperType(constant); } @Override diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StringEqualityNewStringInMethod.java b/java/java-tests/testData/inspection/dataFlow/fixture/StringEqualityNewStringInMethod.java new file mode 100644 index 000000000000..6be634a5565f --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/StringEqualityNewStringInMethod.java @@ -0,0 +1,18 @@ +public class StringEqualityNewStringInMethod { + // IDEA-265089 + public boolean bad() { + return "baah".equals(toString("baah".getBytes("UTF-8"))); + } + + public boolean good() { + return "baah".equals(new String("baah".getBytes("UTF-8"), 0, 4, "UTF-8")); + } + + public boolean good2() { + return toString("baah".getBytes("UTF-8")).equals("baah"); + } + + private static String toString(final byte[] data) { + return new String(data, 0, 4, "UTF-8"); + } +} \ 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 d89e591109eb..10fb1cf899ea 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -622,6 +622,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testVoidIsAlwaysNull() { doTest(); } public void testImpossibleType() { doTest(); } public void testStringEquality() { doTest(); } + public void testStringEqualityNewStringInMethod() { doTest(); } public void testAssignmentFieldAliasing() { doTest(); } public void testNewBoxedNumberEquality() { doTest(); } public void testBoxingIncorrectLiteral() { doTest(); }