diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java index 5b3058c9c6fa..5c11c64277d5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullParameterConstraintChecker.java @@ -50,10 +50,12 @@ import java.util.Set; class NullParameterConstraintChecker extends DataFlowRunner { private final Set myPossiblyViolatedParameters; private final Set myUsedParameters; + private final Set myParametersWithSuccessfulExecutionInNotNullState; private NullParameterConstraintChecker(Collection parameters) { super(false, true); myPossiblyViolatedParameters = new THashSet<>(parameters); + myParametersWithSuccessfulExecutionInNotNullState = new THashSet<>(); myUsedParameters = new THashSet<>(); } @@ -74,10 +76,14 @@ class NullParameterConstraintChecker extends DataFlowRunner { } if (nullableParameters.isEmpty()) return PsiParameter.EMPTY_ARRAY; - final NullParameterConstraintChecker checker = new NullParameterConstraintChecker(nullableParameters); + NullParameterConstraintChecker checker = new NullParameterConstraintChecker(nullableParameters); checker.analyzeMethod(method.getBody(), new StandardInstructionVisitor()); - return checker.myPossiblyViolatedParameters.stream().filter(checker.myUsedParameters::contains).toArray(PsiParameter[]::new); + return checker.myPossiblyViolatedParameters + .stream() + .filter(checker.myUsedParameters::contains) + .filter(checker.myParametersWithSuccessfulExecutionInNotNullState::contains) + .toArray(PsiParameter[]::new); } @NotNull @@ -108,7 +114,10 @@ class NullParameterConstraintChecker extends DataFlowRunner { DfaMemoryState memState = instructionState.getMemoryState(); for (PsiParameter parameter : myPossiblyViolatedParameters.toArray(new PsiParameter[myPossiblyViolatedParameters.size()])) { final DfaVariableValue dfaVar = getFactory().getVarFactory().createVariableValue(parameter, false); - if (!memState.isNotNull(dfaVar)) { + if (memState.isNotNull(dfaVar)) { + myParametersWithSuccessfulExecutionInNotNullState.add(parameter); + } + else { myPossiblyViolatedParameters.remove(parameter); } } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NullArgumentIfMethodExecutionFailsAnyway.java b/java/java-tests/testData/inspection/dataFlow/fixture/NullArgumentIfMethodExecutionFailsAnyway.java new file mode 100644 index 000000000000..06068fefa895 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/NullArgumentIfMethodExecutionFailsAnyway.java @@ -0,0 +1,15 @@ +class Test { + private static void printAndThrow(String message, Throwable cause) { + if (message != null) { + System.err.println(message); + } + if (cause != null) { + cause.printStackTrace(); + } + throw new IllegalStateException(); + } + public static void main(String[] args) { + printAndThrow("test", null); + printAndThrow(null, new NullPointerException()); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java index 72da2e80e1ee..c38437578c7f 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java @@ -117,6 +117,10 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { doTest(); } + public void testNullArgumentIfMethodExecutionFailsAnyway() { + doTest(); + } + public void testNullableArrayComponent() { setupCustomAnnotations(); DataFlowInspection inspection = new DataFlowInspection();