new overload resolution: reject complete normally when last instruction is return (IDEA-134808)

This commit is contained in:
Anna Kozlova
2014-12-29 18:57:39 +01:00
parent fe898d0905
commit 658607d9c2
3 changed files with 70 additions and 2 deletions
@@ -726,9 +726,15 @@ public class ControlFlowUtil {
if (nextOffset > flow.getSize()) nextOffset = flow.getSize();
if (offset > endOffset) return;
int throwToOffset = instruction.offset;
boolean isNormal;
boolean isNormal = false;
if (throwToOffset == nextOffset) {
isNormal = nextOffset == endOffset || throwToOffset <= endOffset && !isLeaf(nextOffset) && canCompleteNormally[nextOffset];
if (nextOffset == endOffset) {
final Instruction lastInstruction = flow.getInstructions().get(endOffset - 1);
isNormal = !(lastInstruction instanceof GoToInstruction && ((GoToInstruction)lastInstruction).isReturn);
}
isNormal |= throwToOffset <= endOffset && !isLeaf(nextOffset) && canCompleteNormally[nextOffset];
}
else {
isNormal = canCompleteNormally[nextOffset];
@@ -0,0 +1,58 @@
class Test {
public interface A<E extends Throwable> {
Object call() throws E;
}
public interface B<E extends Throwable> {
void call() throws E;
}
static Object method(A lambda) {
System.out.println("A::");
try {
lambda.call();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
static void method(B lambda) {
System.out.println("B::");
try {
lambda.call();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
static Object returns(String s) throws Exception {
System.out.println(s); return null;
}
static void voids(String s) throws Exception {
System.out.println(s);
}
public static void main(String[] args) {
method(() -> {
voids("-> B");
});
method(() -> voids("-> B"));
method(() -> {
return returns("-> A");
});
method(() -> returns("-> A") );
method(() -> {
returns("-> B");
});
}
}
@@ -47,6 +47,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testVoidValueCompatibilityCantCompleteNormallyWithCallWithExceptionAsLastReturnStatement() throws Exception {
doTest();
}
public void testIDEA102800() throws Exception {
doTest();
}