JVM_IR KT-47492 fix 'for' loop generation

This commit is contained in:
Dmitry Petrov
2021-06-28 16:21:39 +03:00
committed by TeamCityServer
parent 6993b86d3b
commit 768afc5ba4
11 changed files with 204 additions and 1 deletions
@@ -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 {
@@ -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
View File
@@ -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"
}
+20
View File
@@ -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"
}
+19
View File
@@ -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"
}
@@ -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 {
@@ -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 {
@@ -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");
@@ -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");
@@ -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");
@@ -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");