JVM_IR KT-47492 fix 'for' loop generation
This commit is contained in:
committed by
TeamCityServer
parent
6993b86d3b
commit
768afc5ba4
+18
@@ -29694,6 +29694,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
|
||||
+40
-1
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
@@ -1061,9 +1062,47 @@ class ExpressionCodegen(
|
||||
val entry = markNewLabel()
|
||||
val endLabel = linkedLabel()
|
||||
val continueLabel = linkedLabel()
|
||||
|
||||
val loopInfo = LoopInfo(loop, continueLabel, endLabel)
|
||||
|
||||
// If we have a 'for' loop transformed into a 'do-while' loop,
|
||||
// then corresponding loop variable initialization should happen before we mark loop end and loop continue labels,
|
||||
// because loop variable can be used in the loop condition,
|
||||
// and corresponding slot might contain arbitrary garbage left over from previous computations (see KT-47492).
|
||||
// TODO consider adding special intrinsics for loop body markers instead of generating them manually.
|
||||
if (loop.origin == IrStatementOrigin.FOR_LOOP_INNER_WHILE) {
|
||||
val body = loop.body
|
||||
if (body is IrComposite && body.origin == IrStatementOrigin.FOR_LOOP_INNER_WHILE && body.statements.isNotEmpty()) {
|
||||
val forLoopNext = body.statements[0]
|
||||
if (forLoopNext is IrComposite && forLoopNext.origin == IrStatementOrigin.FOR_LOOP_NEXT) {
|
||||
// We have a 'for' loop transformed into a 'do-while' loop.
|
||||
// Generate it's loop variable initialization,
|
||||
// then mark loop end and loop continue labels,
|
||||
// then generate the for loop body.
|
||||
val forLoopBody = IrCompositeImpl(
|
||||
body.startOffset, body.endOffset, body.type, body.origin,
|
||||
body.statements.subList(1, body.statements.size)
|
||||
)
|
||||
data.withBlock(loopInfo) {
|
||||
forLoopNext.accept(this, data).discard()
|
||||
mv.fakeAlwaysFalseIfeq(continueLabel)
|
||||
mv.fakeAlwaysFalseIfeq(endLabel)
|
||||
forLoopBody.accept(this, data).discard()
|
||||
mv.visitLabel(continueLabel)
|
||||
loop.condition.markLineNumber(true)
|
||||
loop.condition.accept(this, data).coerceToBoolean().jumpIfTrue(entry)
|
||||
}
|
||||
mv.mark(endLabel)
|
||||
addInlineMarker(mv, false)
|
||||
return unitValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We have a regular 'do-while' loop. Proceed as usual.
|
||||
mv.fakeAlwaysFalseIfeq(continueLabel)
|
||||
mv.fakeAlwaysFalseIfeq(endLabel)
|
||||
data.withBlock(LoopInfo(loop, continueLabel, endLabel)) {
|
||||
data.withBlock(loopInfo) {
|
||||
loop.body?.accept(this, data)?.discard()
|
||||
mv.visitLabel(continueLabel)
|
||||
loop.condition.markLineNumber(true)
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun p() {}
|
||||
|
||||
fun box(): String {
|
||||
var sum = 1
|
||||
for (i: Int? in sum downTo sum.toULong().countTrailingZeroBits())
|
||||
p()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun a() = 5
|
||||
fun b() = 1
|
||||
fun p() {}
|
||||
|
||||
fun box(): String {
|
||||
when (false) {
|
||||
else -> {
|
||||
val h1 = 1
|
||||
val h2 = 2L
|
||||
val h3 = 3L
|
||||
}
|
||||
}
|
||||
var sum = 1
|
||||
for (i: Int? in a() downTo b())
|
||||
p()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun a() = 5
|
||||
fun b() = 1
|
||||
|
||||
fun p() {}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
val h1 = 1
|
||||
val h2 = 2L
|
||||
val h3 = 3L
|
||||
} catch (e: Exception) { throw e }
|
||||
var sum = 1
|
||||
for (i: Int? in a() downTo b())
|
||||
p()
|
||||
return "OK"
|
||||
}
|
||||
+18
@@ -29652,6 +29652,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
|
||||
+18
@@ -29694,6 +29694,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
|
||||
+15
@@ -25203,6 +25203,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/multiAssignmentIterationOverIntRange.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+15
@@ -19942,6 +19942,21 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/multiAssignmentIterationOverIntRange.kt");
|
||||
|
||||
Generated
+15
@@ -19348,6 +19348,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/multiAssignmentIterationOverIntRange.kt");
|
||||
|
||||
Generated
+15
@@ -19398,6 +19398,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt37370a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492.kt")
|
||||
public void testKt47492() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492a.kt")
|
||||
public void testKt47492a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt47492b.kt")
|
||||
public void testKt47492b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/kt47492b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multiAssignmentIterationOverIntRange.kt")
|
||||
public void testMultiAssignmentIterationOverIntRange() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/multiAssignmentIterationOverIntRange.kt");
|
||||
|
||||
Reference in New Issue
Block a user