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 30eae15890a5..1634815041ce 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 @@ -255,7 +255,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { setVariableState(var, getVariableState(var).withValue(value)); if (value instanceof DfaTypeValue) { - setVariableState(var, getVariableState(var).withNullable(((DfaTypeValue)value).isNullable())); + setVariableState(var, getVariableState(var).withNullability(((DfaTypeValue)value).getNullness())); DfaRelationValue dfaInstanceof = myFactory.getRelationFactory().createRelation(var, value, JavaTokenType.INSTANCEOF_KEYWORD, false); if (((DfaTypeValue)value).isNotNull()) { applyCondition(dfaInstanceof); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index ed52d2c5e78b..126c48ff5fc5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -66,10 +66,11 @@ public class StandardInstructionVisitor extends InstructionVisitor { if (dfaDest instanceof DfaVariableValue) { DfaVariableValue var = (DfaVariableValue) dfaDest; - if (var.getInherentNullability() == Nullness.NOT_NULL) { + final PsiModifierListOwner psi = var.getPsiVariable(); + boolean forceDeclaredNullity = !(psi instanceof PsiParameter && psi.getParent() instanceof PsiParameterList); + if (forceDeclaredNullity && var.getInherentNullability() == Nullness.NOT_NULL) { checkNotNullable(memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression()); } - final PsiModifierListOwner psi = var.getPsiVariable(); if (!(psi instanceof PsiField) || !psi.hasModifierProperty(PsiModifier.VOLATILE)) { memState.setVarValue(var, dfaSource); } diff --git a/java/java-tests/testData/inspection/dataFlow/NotNullLocalVariable/expected.xml b/java/java-tests/testData/inspection/dataFlow/NotNullLocalVariable/expected.xml index 0661e23a2761..580a889dbfd6 100644 --- a/java/java-tests/testData/inspection/dataFlow/NotNullLocalVariable/expected.xml +++ b/java/java-tests/testData/inspection/dataFlow/NotNullLocalVariable/expected.xml @@ -1,8 +1,3 @@ - - Npe.java - 7 - Condition 'o == null' is always false - diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MethodParametersCanChangeNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/MethodParametersCanChangeNullability.java new file mode 100644 index 000000000000..b54637a15225 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/MethodParametersCanChangeNullability.java @@ -0,0 +1,33 @@ +import org.jetbrains.annotations.*; + +class Test { + + @Nullable + String findMessage(@NotNull Element element) { + while (element != null) { + if (element.getMessage() != null) { + return element.getMessage(); + } + element = element.getParent(); + } + return null; + } + + @Nullable + String findMessageWithNullableParent(@NotNull Element element) { + while (element != null) { + if (element.getMessage() != null) { + return element.getMessage(); + } + element = element.getNullableParent(); + } + return null; + } + +} + +interface Element { + Element getParent(); + @Nullable Element getNullableParent(); + @Nullable String getMessage(); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index f502baa392f5..d79d3fca6a90 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -301,6 +301,8 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testAccessingSameArrayElements() { doTest(); } + public void testMethodParametersCanChangeNullability() { doTest(); } + public void testParametersAreNonnullByDefault() { addJavaxNullabilityAnnotations(myFixture); addJavaxDefaultNullabilityAnnotations(myFixture);