diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index d44843547afa..668035b48f0a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -1688,6 +1688,15 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { addInstruction(new MethodCallInstruction(expression, myFactory.createValue(expression), contracts)); anchor = expression; } + processFailResult(contracts, anchor); + + addMethodThrows(method, anchor); + if (expression != null) { + addNullCheck(expression); + } + } + + private void processFailResult(List contracts, PsiExpression anchor) { if (contracts.stream().anyMatch(c -> c.getReturnValue().isFail())) { // if a contract resulted in 'fail', handle it addInstruction(new DupInstruction()); @@ -1699,11 +1708,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { ifNotFail.setOffset(myCurrentFlow.getInstructionCount()); } - - addMethodThrows(method, anchor); - if (expression != null) { - addNullCheck(expression); - } } @Override @@ -1792,7 +1796,9 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { addConditionalErrorThrow(); DfaValue precalculatedNewValue = getPrecalculatedNewValue(expression); List contracts = constructor == null ? Collections.emptyList() : JavaMethodContractUtil.getMethodContracts(constructor); - addInstruction(new MethodCallInstruction(expression, precalculatedNewValue, DfaUtil.addRangeContracts(constructor, contracts))); + contracts = DfaUtil.addRangeContracts(constructor, contracts); + addInstruction(new MethodCallInstruction(expression, precalculatedNewValue, contracts)); + processFailResult(contracts, expression); addMethodThrows(constructor, expression); } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ContractConstructor.java b/java/java-tests/testData/inspection/dataFlow/fixture/ContractConstructor.java index fc1d5fa6cae8..093f8159b07d 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ContractConstructor.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ContractConstructor.java @@ -7,11 +7,11 @@ class CandidateInfo { } static void test() { - new CandidateInfo(null, true, false); - new CandidateInfo(null, true, true); + if (Math.random() > 0.5) new CandidateInfo(null, true, false); + if (Math.random() > 0.5) new CandidateInfo(null, true, true); - new CandidateInfo(null, false, true); - new CandidateInfo(new Object(), true, true); - new CandidateInfo(new Object(), false, true); + if (Math.random() > 0.5) new CandidateInfo(null, false, true); + if (Math.random() > 0.5) new CandidateInfo(new Object(), true, true); + if (Math.random() > 0.5) new CandidateInfo(new Object(), false, true); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/PresizedList.java b/java/java-tests/testData/inspection/dataFlow/fixture/PresizedList.java new file mode 100644 index 000000000000..5f1bf4e1be87 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/PresizedList.java @@ -0,0 +1,10 @@ +import java.util.*; + +public class PresizedList { + void test(int size) { + List list = new ArrayList<>(size); + for (int i = 0; i < list.size(); i++) { + list.add(i, ""); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index 4944e1c13122..f6534018bbcc 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -686,4 +686,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testInferenceInPrivateOrLocalClass() { doTest(); } public void testArraysCopyOf() { doTest(); } public void testArrayNegativeSize() { doTest(); } + public void testPresizedList() { doTest(); } }