JVM: Break infinite loop in finding meaningful instruction

during tail-call optimization.

There can be code, where all next instructions are non-meaningful and
there is a back-edge, for example, while(true){}. Previously, analyzer
incorrectly assumed, that this cannot happen. Now, it keeps track of
visited instructions and says, that there is no meaningful instruction
in such case.
 #KT-56815 Fixed
This commit is contained in:
Ilmir Usmanov
2023-02-21 18:34:23 +01:00
committed by Space Team
parent 550b4f1f11
commit b3890885c4
14 changed files with 109 additions and 5 deletions
@@ -76,11 +76,18 @@ internal fun MethodNode.addCoroutineSuspendedChecks(suspensionPoints: List<Suspe
}
}
private tailrec fun AbstractInsnNode?.skipUntilMeaningful(): AbstractInsnNode? = when {
this == null -> null
opcode == Opcodes.NOP || !isMeaningful -> next.skipUntilMeaningful()
opcode == Opcodes.GOTO -> (this as JumpInsnNode).label.skipUntilMeaningful()
else -> this
private fun AbstractInsnNode?.skipUntilMeaningful(): AbstractInsnNode? {
var cursor: AbstractInsnNode? = this ?: return null
val visited = mutableSetOf<AbstractInsnNode>()
while (cursor != null) {
if (!visited.add(cursor)) return null
when {
cursor.opcode == Opcodes.NOP || !cursor.isMeaningful -> cursor = cursor.next
cursor.opcode == Opcodes.GOTO -> cursor = (cursor as JumpInsnNode).label
else -> return cursor
}
}
return null
}
private val AbstractInsnNode.nextMeaningful: AbstractInsnNode?
@@ -10291,6 +10291,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -10291,6 +10291,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -0,0 +1,27 @@
// WITH_STDLIB
import kotlin.coroutines.*
suspend fun test() {
Nexus.initialize1()
while (true) { }
}
object Nexus {
suspend fun initialize1() {
}
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(Continuation(EmptyCoroutineContext) {
it.getOrThrow()
})
}
fun box(): String {
builder {
suspendCoroutine<Unit> {}
test()
}
return "OK"
}
@@ -10069,6 +10069,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -10291,6 +10291,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -7927,6 +7927,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineFunInGenericClass.kt");
@@ -7083,6 +7083,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -7179,6 +7179,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -7179,6 +7179,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -7179,6 +7179,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -8136,6 +8136,12 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -8047,6 +8047,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@Test
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@Test
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
@@ -6317,6 +6317,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
}
@TestMetadata("infiniteLoopInNextMeaningful.kt")
public void testInfiniteLoopInNextMeaningful() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/infiniteLoopInNextMeaningful.kt");
}
@TestMetadata("inlineFunInGenericClass.kt")
public void testInlineFunInGenericClass() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/inlineFunInGenericClass.kt");