diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index 82a0cc5358c3..9364e3ecd374 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -718,8 +718,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState { boolean resetNullability = isNotNull(field); flushVariable(field); if (resetNullability) { - getVariableState(field).setNullable(false); } + getVariableState(field).setNullable(false); } } @@ -728,15 +728,15 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return; } - doFlash(variable); + doFlush(variable); } @Override public void flushVariableOutOfScope(DfaVariableValue variable) { - doFlash(variable); + doFlush(variable); } - private void doFlash(DfaVariableValue varPlain) { + private void doFlush(DfaVariableValue varPlain) { DfaVariableValue varNegated = (DfaVariableValue)varPlain.createNegated(); final int idPlain = varPlain.getID(); diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java index 518b4621bab1..e9b2754724d0 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java @@ -150,6 +150,9 @@ public abstract class InstructionVisitor { } public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { + if (instruction.isFieldReference()) { + memState.fieldReferenced(); + } memState.push(instruction.getValue()); return nextInstruction(instruction, runner, memState); } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java index f6c1257c8ad5..9bf11de1cb54 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java @@ -31,6 +31,8 @@ import com.intellij.codeInspection.dataFlow.InstructionVisitor; import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiReferenceExpression; import org.jetbrains.annotations.NotNull; public class PushInstruction extends Instruction { @@ -59,4 +61,8 @@ public class PushInstruction extends Instruction { public String toString() { return "PUSH " + myValue; } + + public boolean isFieldReference() { + return myPlace instanceof PsiReferenceExpression && ((PsiReferenceExpression)myPlace).resolve() instanceof PsiField; + } } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java b/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java new file mode 100644 index 000000000000..411e3a086efc --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java @@ -0,0 +1,20 @@ +public class Bar { + private Object field; + private final Object lock = new Object(); + + public void main() { + synchronized (lock) { + if (field != null) { + return; + } + } + synchronized (lock) { + if (field != null) { + return; + } + if (field == null) { + System.out.println(); + } + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java index f01b63465068..251b4e6ed81c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java @@ -55,4 +55,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas public void testBigMethodNotComplex() throws Throwable { doTest(); } public void testTernaryInWhileNotComplex() throws Throwable { doTest(); } public void testTryCatchInForNotComplex() throws Throwable { doTest(); } + public void testFieldChangedBetweenSynchronizedBlocks() throws Throwable { doTest(); } + } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index dc0428ae3fa8..6e6ed040da94 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -9,9 +9,12 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.slice.SliceTreeTest; import com.intellij.codeInspection.dataFlow.DataFlowInspection; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.testFramework.InspectionTestCase; +import junit.framework.Test; +import junit.framework.TestSuite; import org.jetbrains.annotations.NonNls; public class DataFlowInspectionTest extends InspectionTestCase { @@ -148,4 +151,13 @@ public class DataFlowInspectionTest extends InspectionTestCase { //public void testIDEADEV11033() throws Exception { doTest15(); } public void testSwitchEnumCases() throws Exception { doTest15(); } + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTestSuite(DataFlowInspectionFixtureTest.class); + suite.addTestSuite(DataFlowInspectionTest.class); + suite.addTestSuite(SliceTreeTest.class); + return suite; + } + }