From 48848a8a7b01e1bbc0f33e9e835801ebb9bbd492 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Sat, 3 Mar 2018 15:02:58 +0700 Subject: [PATCH] IDEA-187645 NPE warning is not issued when "null -> null" method is called with Nullable argument --- .../dataFlow/value/DfaRelationValue.java | 13 +++++++++-- .../fixture/ContractWithNullable.java | 22 ++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java index 09d7f5692f41..24e48ae92fda 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.dataFlow.value; +import com.intellij.codeInspection.dataFlow.DfaFactType; import com.intellij.openapi.util.Trinity; import com.intellij.psi.JavaTokenType; import com.intellij.psi.tree.IElementType; @@ -189,14 +190,22 @@ public class DfaRelationValue extends DfaValue { return createCanonicalRelation(dfaLeft, relationType, dfaRight); } if (dfaLeft instanceof DfaFactMapValue && dfaRight instanceof DfaConstValue) { - return createCanonicalRelation(DfaUnknownValue.getInstance(), relationType, dfaRight); + return createConstBasedRelation((DfaFactMapValue)dfaLeft, relationType, (DfaConstValue)dfaRight); } else if (dfaRight instanceof DfaFactMapValue && dfaLeft instanceof DfaConstValue) { - return createCanonicalRelation(DfaUnknownValue.getInstance(), relationType, dfaLeft); + return createConstBasedRelation((DfaFactMapValue)dfaRight, relationType, (DfaConstValue)dfaLeft); } return null; } + @NotNull + private DfaRelationValue createConstBasedRelation(DfaFactMapValue dfaLeft, RelationType relationType, DfaConstValue dfaRight) { + if (dfaRight.getValue() == null && Boolean.TRUE.equals(dfaLeft.get(DfaFactType.CAN_BE_NULL))) { + return createCanonicalRelation(myFactory.getFactValue(DfaFactType.CAN_BE_NULL, Boolean.TRUE), relationType, dfaRight); + } + return createCanonicalRelation(DfaUnknownValue.getInstance(), relationType, dfaRight); + } + @NotNull private DfaRelationValue createCanonicalRelation(@NotNull final DfaValue dfaLeft, @NotNull RelationType relationType, diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java index 99831720bfe7..5c21de8ec170 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractWithNullable.java @@ -2,6 +2,26 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +class Test2 { + interface Project {} + interface Sdk {} + interface Version {} + + @NotNull + native static Test2 getInstance(Project project); + + @Nullable + native Sdk getProjectSdk(); + + @Contract("null -> null") + native static Version getVersion(@Nullable Sdk sdk); + + static void test(Project project) { + Version version = getVersion(getInstance(project).getProjectSdk()); + System.out.println(version.hashCode()); + } +} + class Foo { public void main(@NotNull Object nn) { @@ -58,4 +78,4 @@ class Test { String test() { return convert(getName()); } -} \ No newline at end of file +}