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:
committed by
Space Team
parent
550b4f1f11
commit
b3890885c4
+12
-5
@@ -76,11 +76,18 @@ internal fun MethodNode.addCoroutineSuspendedChecks(suspensionPoints: List<Suspe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private tailrec fun AbstractInsnNode?.skipUntilMeaningful(): AbstractInsnNode? = when {
|
private fun AbstractInsnNode?.skipUntilMeaningful(): AbstractInsnNode? {
|
||||||
this == null -> null
|
var cursor: AbstractInsnNode? = this ?: return null
|
||||||
opcode == Opcodes.NOP || !isMeaningful -> next.skipUntilMeaningful()
|
val visited = mutableSetOf<AbstractInsnNode>()
|
||||||
opcode == Opcodes.GOTO -> (this as JumpInsnNode).label.skipUntilMeaningful()
|
while (cursor != null) {
|
||||||
else -> this
|
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?
|
private val AbstractInsnNode.nextMeaningful: AbstractInsnNode?
|
||||||
|
|||||||
+6
@@ -10291,6 +10291,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -10291,6 +10291,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
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"
|
||||||
|
}
|
||||||
+6
@@ -10069,6 +10069,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -10291,6 +10291,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+5
@@ -7927,6 +7927,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/inlineFunInGenericClass.kt");
|
runTest("compiler/testData/codegen/box/coroutines/inlineFunInGenericClass.kt");
|
||||||
|
|||||||
+6
@@ -7083,6 +7083,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -7179,6 +7179,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -7179,6 +7179,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -7179,6 +7179,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -8136,6 +8136,12 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -8047,6 +8047,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineFunInGenericClass.kt")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
|
|||||||
Generated
+5
@@ -6317,6 +6317,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/indirectInlineUsedAsNonInline.kt");
|
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")
|
@TestMetadata("inlineFunInGenericClass.kt")
|
||||||
public void testInlineFunInGenericClass() throws Exception {
|
public void testInlineFunInGenericClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/inlineFunInGenericClass.kt");
|
runTest("compiler/testData/codegen/box/coroutines/inlineFunInGenericClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user