From e9950c0327f65c5d24d515bd4f8cf86185ade690 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 28 Apr 2022 11:31:13 +0200 Subject: [PATCH] [java-dfa] Remove equivalences when flushing qualified methods Fixes IDEA-292808 False positive for "Constant conditions and exceptions": always false IF condition in inner class with use of public method GitOrigin-RevId: b8235e443ecdb9c4a37b4c16b8814e48b607a2d3 --- .../fixture/ChangeFieldUsedInPureMethod.java | 24 +++++++++++++++++++ .../DataFlowInspectionTest.java | 1 + .../dataFlow/memory/DfaMemoryStateImpl.java | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/ChangeFieldUsedInPureMethod.java diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ChangeFieldUsedInPureMethod.java b/java/java-tests/testData/inspection/dataFlow/fixture/ChangeFieldUsedInPureMethod.java new file mode 100644 index 000000000000..6adbca18711e --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ChangeFieldUsedInPureMethod.java @@ -0,0 +1,24 @@ +// IDEA-292808 +class Test { + private class Inner { + private boolean firstCheckOk; + private boolean secondCheckOk; + public void firstCheck(boolean ok) { + boolean oldOk = isOk(); + this.firstCheckOk = ok; + boolean newOk = isOk(); + if (oldOk != newOk) + System.out.println(newOk); + } + public void secondCheck(boolean ok) { + boolean oldOk = isOk(); + this.secondCheckOk = ok; + boolean newOk = isOk(); + if (oldOk != newOk) + System.out.println(newOk); + } + public boolean isOk() { + return firstCheckOk || secondCheckOk; + } + } +} \ 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 c0d3f8121cdf..c0b1fd3b961d 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -719,4 +719,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testBoxingInConstructorArguments() { doTest(); } public void testBoxingInArrayDeclaration() { doTest(); } public void testNestedVersusSuper() { doTest(); } + public void testChangeFieldUsedInPureMethod() { doTest(); } } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java index 815fbec9509c..651fdd56c474 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/dataFlow/memory/DfaMemoryStateImpl.java @@ -1381,8 +1381,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState { private void flushQualifiedMethods(@NotNull DfaVariableValue variable) { if (variable.isFlushableByCalls()) { // Flush method results on field write - List toFlush = - ContainerUtil.filter(myVariableTypes.keySet(), DfaVariableValue::containsCalls); + List toFlush = StreamEx.of(myEqClasses).flatMap(cls -> cls == null ? null : StreamEx.of(cls.iterator())) + .append(myVariableTypes.keySet()).filter(DfaVariableValue::containsCalls).toList(); toFlush.forEach(val -> doFlush(val, true)); } }