IDEA-204641 Exception throwing analysis doesn't account for runtime exceptions in functions

This commit is contained in:
Tagir Valeev
2018-12-24 15:47:04 +07:00
parent 0c2a9a61f4
commit 008d3a6e49
3 changed files with 28 additions and 10 deletions
@@ -690,7 +690,10 @@ public class CFGBuilder {
}
// Unknown function
flushFields();
PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalExpression.getType());
myAnalyzer.addConditionalRuntimeThrow();
PsiType functionalInterfaceType = functionalExpression.getType();
myAnalyzer.addMethodThrows(LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType), null);
PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);
if (returnType != null) {
push(getFactory().createTypeValue(returnType, DfaPsiUtil.getTypeNullability(returnType)));
}
@@ -1041,7 +1041,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
finishElement(statement);
}
private void addConditionalRuntimeThrow() {
void addConditionalRuntimeThrow() {
if (!shouldHandleException()) {
return;
}
@@ -1655,8 +1655,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
finishElement(expression);
}
private void addMethodThrows(PsiMethod method, @Nullable PsiElement explicitCall) {
if (method != null) {
void addMethodThrows(PsiMethod method, @Nullable PsiElement explicitCall) {
if (method != null && shouldHandleException()) {
addThrows(explicitCall, method.getThrowsList().getReferencedTypes());
}
}
@@ -1774,9 +1774,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
ifNotFail.setOffset(myCurrentFlow.getInstructionCount());
}
if (shouldHandleException()) {
addMethodThrows(method, anchor);
}
addMethodThrows(method, anchor);
}
/**
@@ -1862,9 +1860,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
List<? extends MethodContract> contracts = constructor == null ? Collections.emptyList() : JavaMethodContractUtil.getMethodContracts(constructor);
addInstruction(new MethodCallInstruction(expression, precalculatedNewValue, contracts));
if (shouldHandleException()) {
addMethodThrows(constructor, expression);
}
addMethodThrows(constructor, expression);
}
finishElement(expression);
@@ -2,6 +2,7 @@ import foo.*;
import java.util.Map;
import java.util.HashMap;
import java.util.function.Function;
class MapUpdateInlining {
void testKey(Map<String, String> map) {
@@ -82,4 +83,22 @@ class MapUpdateInlining {
}
native void doSmth();
// IDEA-204641
public static void testAnyLambda(@NotNull Function<String, String> lambda) {
Map<String, String> map = new HashMap<>();
Throwable thrown = null;
try {
map.computeIfAbsent("a", lambda);
}
catch (Throwable t) {
thrown = t;
throw t;
}
finally {
if (thrown != null) { // possible
int x = 0;
}
}
}
}