Fix verify error with 'return when/if/try' in suspend function

The problem appears for tail-optimized suspend functions,
we erroneously assumed that when/if/try expressions in tail-call
position have simple types like `I` while actually, they can return SUSPENDED
object, i.e. must have `java/lang/Object` as return type.

But this only concerns branching operations in tail-call position,
so we have to make an additional analysis for remembering whether
a given expression is in a tail-call position.

Also, it's important here that we now assume
the return type of the current function  as `java/lang/Object`
that is necessary to avoid wrong checkcasts.

 #KT-15364 Fixed
This commit is contained in:
Denis Zharkov
2017-01-12 15:34:31 +03:00
parent de9c41c412
commit 2286027bed
14 changed files with 324 additions and 32 deletions
@@ -5135,6 +5135,33 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
}
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TailOperations extends AbstractLightAnalysisModeCodegenTest {
public void testAllFilesPresentInTailOperations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailOperations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("suspendWithIf.kt")
public void testSuspendWithIf() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailOperations/suspendWithIf.kt");
doTest(fileName);
}
@TestMetadata("suspendWithTryCatch.kt")
public void testSuspendWithTryCatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailOperations/suspendWithTryCatch.kt");
doTest(fileName);
}
@TestMetadata("suspendWithWhen.kt")
public void testSuspendWithWhen() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailOperations/suspendWithWhen.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/coroutines/unitTypeReturn")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)