dfa: mark ephemeral states even when there's no way of checking contract condition (IDEA-137604)

This commit is contained in:
peter
2015-03-17 13:03:44 +01:00
parent cf86586506
commit c72c1bf7c6
3 changed files with 31 additions and 3 deletions
@@ -262,13 +262,18 @@ public class StandardInstructionVisitor extends InstructionVisitor {
MethodContract.ValueConstraint constraint = contract.arguments[i];
DfaConstValue expectedValue = constraint.getComparisonValue(factory);
if (expectedValue == null) continue;
boolean nullContract = expectedValue == constFactory.getNull();
boolean invertCondition = constraint.shouldUseNonEqComparison();
DfaValue condition = factory.getRelationFactory().createRelation(argValue, expectedValue, EQEQ, invertCondition);
if (condition == null) {
if (!(argValue instanceof DfaConstValue)) {
for (DfaMemoryState state : states) {
falseStates.add(state.createCopy());
DfaMemoryState falseCopy = state.createCopy();
if (nullContract) {
(invertCondition ? falseCopy : state).markEphemeral();
}
falseStates.add(falseCopy);
}
continue;
}
@@ -277,7 +282,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
LinkedHashSet<DfaMemoryState> nextStates = ContainerUtil.newLinkedHashSet();
for (DfaMemoryState state : states) {
boolean unknownVsNull = expectedValue == constFactory.getNull() &&
boolean unknownVsNull = nullContract &&
argValue instanceof DfaVariableValue &&
((DfaMemoryStateImpl)state).getVariableState((DfaVariableValue)argValue).getNullability() == Nullness.UNKNOWN;
DfaMemoryState falseCopy = state.createCopy();
@@ -0,0 +1,22 @@
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
class TestCase {
private void countWordsWarning() {
// no warnings should be here
String s = normalizeSpace(unknown()).trim();
String s3 = normalizeSpaceInverted(unknown()).trim();
String s4 = <warning descr="Method invocation 'normalizeSpace(null).trim()' may produce 'java.lang.NullPointerException'">normalizeSpace(null).trim()</warning>;
}
public static native String unknown();
@Contract("null->null")
public static native String normalizeSpace(@Nullable String str);
@Contract("!null->!null; _->null")
public static native String normalizeSpaceInverted(String str);
}
@@ -222,6 +222,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testContractWithNullable() { doTest(); }
public void testContractWithNotNull() { doTest(); }
public void testContractPreservesUnknownNullability() { doTest(); }
public void testContractPreservesUnknownMethodNullability() { doTest(); }
public void testContractSeveralClauses() { doTest(); }
public void testContractVarargs() { doTest(); }