From 19ffdbe7aa68045d0a5e8fee2b3113d90b7d3ad7 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 22 Dec 2016 15:12:03 +0100 Subject: [PATCH] avoid false positive contract violations when the control flow goes through unknown conditions (IDEA-164883) --- .../codeInspection/dataFlow/ContractChecker.java | 14 ++++++-------- .../dataFlow/contractCheck/UnknownIfCondition.java | 12 ++++++++++++ .../intellij/codeInspection/ContractCheckTest.java | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/contractCheck/UnknownIfCondition.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java index 98f5446a6f2d..b9a160440209 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractChecker.java @@ -15,14 +15,8 @@ */ package com.intellij.codeInspection.dataFlow; -import com.intellij.codeInspection.dataFlow.instructions.CheckReturnValueInstruction; -import com.intellij.codeInspection.dataFlow.instructions.Instruction; -import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction; -import com.intellij.codeInspection.dataFlow.instructions.ReturnInstruction; -import com.intellij.codeInspection.dataFlow.value.DfaConstValue; -import com.intellij.codeInspection.dataFlow.value.DfaValue; -import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; -import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.codeInspection.dataFlow.instructions.*; +import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -104,6 +98,10 @@ class ContractChecker extends DataFlowRunner { return DfaInstructionState.EMPTY_ARRAY; } + if (instruction instanceof ConditionalGotoInstruction && memState.peek() == DfaUnknownValue.getInstance()) { + return DfaInstructionState.EMPTY_ARRAY; + } + return super.acceptInstruction(visitor, instructionState); } diff --git a/java/java-tests/testData/inspection/dataFlow/contractCheck/UnknownIfCondition.java b/java/java-tests/testData/inspection/dataFlow/contractCheck/UnknownIfCondition.java new file mode 100644 index 000000000000..b7b09ea89904 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/contractCheck/UnknownIfCondition.java @@ -0,0 +1,12 @@ +class Test { + + @org.jetbrains.annotations.Contract("null->false") + public static boolean smth(Object context) { + if (someMethodWithUnknownContract(context)) { + return true; + } + return false; + } + + private static native boolean someMethodWithUnknownContract(Object o); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ContractCheckTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/ContractCheckTest.java index 8d5eccab914c..2ec22019a95a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/ContractCheckTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/ContractCheckTest.java @@ -47,4 +47,5 @@ public class ContractCheckTest extends LightCodeInsightFixtureTestCase { public void testCheckConstructorContracts() { doTest(); } public void testPassingVarargsToDelegate() { doTest(); } + public void testUnknownIfCondition() { doTest(); } }