dfa: pop all the contract-unchecked arguments from stack (IDEA-112500)

This commit is contained in:
peter
2013-09-04 18:40:23 +02:00
parent 6c2ead1c62
commit 9c9e366bce
3 changed files with 28 additions and 6 deletions
@@ -104,7 +104,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
private boolean myRecursionStopper = false;
private void addInstruction(Instruction i) {
private <T extends Instruction> T addInstruction(T i) {
ProgressManager.checkCanceled();
if (!myRecursionStopper) {
@@ -121,6 +121,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
}
myCurrentFlow.addInstruction(i);
return i;
}
private int getEndOffset(PsiElement element) {
@@ -1365,7 +1366,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
final int exitPoint = getEndOffset(expression);
List<ConditionalGotoInstruction> gotoContractFalse = new SmartList<ConditionalGotoInstruction>();
List<GotoInstruction> gotoContractFalse = new SmartList<GotoInstruction>();
for (int i = args.length - 1; i >= 0; i--) {
ValueConstraint arg = contract.arguments[i];
if (arg == ValueConstraint.NULL_VALUE || arg == ValueConstraint.NOT_NULL_VALUE) {
@@ -1378,9 +1379,13 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
}
boolean expectingTrueOnStack = arg == ValueConstraint.NULL_VALUE || arg == ValueConstraint.TRUE_VALUE;
ConditionalGotoInstruction condGoto = new ConditionalGotoInstruction(-1, expectingTrueOnStack, null);
gotoContractFalse.add(condGoto);
addInstruction(condGoto);
ConditionalGotoInstruction continueCheckingContract = addInstruction(new ConditionalGotoInstruction(-1, !expectingTrueOnStack, null));
for (int j = 0; j < i; j++) {
addInstruction(new PopInstruction());
}
gotoContractFalse.add(addInstruction(new GotoInstruction(-1)));
continueCheckingContract.setOffset(myCurrentFlow.getInstructionCount());
}
// if contract is true
@@ -1420,7 +1425,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
}
// if contract is false
for (ConditionalGotoInstruction instruction : gotoContractFalse) {
for (GotoInstruction instruction : gotoContractFalse) {
instruction.setOffset(myCurrentFlow.getInstructionCount());
}
}
@@ -0,0 +1,16 @@
import org.jetbrains.annotations.Contract;
public class Foo {
public void main(String[] args) {
for (int i = 0; i < 10; i++) {
assertTrue("str", true);
}
}
@Contract("_, false->fail")
void assertTrue(String msg, boolean value) {
}
}
@@ -283,6 +283,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
}
public void testContractAnnotation() { doTest(); }
public void testContractInLoopNotTooComplex() { doTest(); }
public void testBoxingImpliesNotNull() { doTest(); }
public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); }
public void testNoGenericCCE() { doTest(); }