Correctly map container element type in intrinsic for withIndex

In case of arrays, we couldn't distinguish array of boxed Ints
from array of primitive Ints.

 #KT-22904 Fixed Target versions 1.2.40
This commit is contained in:
Dmitry Petrov
2018-02-19 14:53:36 +03:00
parent 2028ec3ce8
commit 99cea07bf4
14 changed files with 321 additions and 5 deletions
@@ -29,7 +29,7 @@ abstract class AbstractWithIndexForLoopGenerator(
private val bodyEnd = Label()
private val leaveTasks = arrayListOf<() -> Unit>()
protected class LoopComponent(val parameterVar: Int, val parameterType: Type, val elementType: Type)
protected class LoopComponent(val parameterVar: Int, val parameterType: Type, val componentType: Type)
protected val indexLoopComponent: LoopComponent? = loopParameter.entries.getOrNull(0)?.resolveLoopComponent()
protected val elementLoopComponent: LoopComponent? = loopParameter.entries.getOrNull(1)?.resolveLoopComponent()
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.range.forLoop
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.generateCallReceiver
import org.jetbrains.kotlin.codegen.range.forLoop.AbstractWithIndexForLoopGenerator
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtForExpression
@@ -25,6 +24,7 @@ class ArrayWithIndexForLoopGenerator(
) : AbstractWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) {
private val arrayType = codegen.asmType(ExpressionCodegen.getExpectedReceiverType(rangeCall))
private val arrayElementType = arrayType.elementType
private var arrayVar = -1
private var arrayLengthVar = -1
@@ -61,9 +61,9 @@ class ArrayWithIndexForLoopGenerator(
if (elementLoopComponent != null) {
v.load(arrayVar, AsmTypes.OBJECT_TYPE)
v.load(indexVar, Type.INT_TYPE)
v.aload(elementLoopComponent.elementType)
StackValue.local(elementLoopComponent.parameterVar, elementLoopComponent .parameterType)
.store(StackValue.onStack(elementLoopComponent .elementType), v)
v.aload(arrayElementType)
StackValue.local(elementLoopComponent.parameterVar, elementLoopComponent.parameterType)
.store(StackValue.onStack(arrayElementType), v)
}
}
@@ -0,0 +1,18 @@
// WITH_RUNTIME
val arr = byteArrayOf(10, 20, 30, 40)
fun foo(xs: Any): String {
if (xs !is ByteArray) return "not a ByteArray"
val s = StringBuilder()
for ((index, x) in xs.withIndex()) {
s.append("$index:$x;")
}
return s.toString()
}
fun box(): String {
val ss = foo(arr)
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,12 @@
// WITH_RUNTIME
val arr = byteArrayOf(10, 20, 30, 40)
fun box(): String {
val s = StringBuilder()
for ((index, x) in arr.withIndex()) {
s.append("$index:$x;")
}
val ss = s.toString()
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,12 @@
// WITH_RUNTIME
val arr = arrayOf(10, 20, 30, 40)
fun box(): String {
val s = StringBuilder()
for ((index, x) in arr.withIndex()) {
s.append("$index:$x;")
}
val ss = s.toString()
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,18 @@
// WITH_RUNTIME
val arr = arrayOf(10, 20, 30, 40)
fun foo(xs: Any): String {
if (xs !is Array<*>) return "not an Array<*>"
val s = StringBuilder()
for ((index, x) in xs.withIndex()) {
s.append("$index:$x;")
}
return s.toString()
}
fun box(): String {
val ss = foo(arr)
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,16 @@
// WITH_RUNTIME
val arr = arrayOf(10, 20, 30, 40)
fun <T : Number> foo(xs: Array<T>): String {
val s = StringBuilder()
for ((index, x) in xs.withIndex()) {
s.append("$index:$x;")
}
return s.toString()
}
fun box(): String {
val ss = foo(arr)
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,18 @@
// WITH_RUNTIME
val arr = intArrayOf(10, 20, 30, 40)
fun foo(xs: Any): String {
if (xs !is IntArray) return "not an IntArray"
val s = StringBuilder()
for ((index, x) in xs.withIndex()) {
s.append("$index:$x;")
}
return s.toString()
}
fun box(): String {
val ss = foo(arr)
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,18 @@
// WITH_RUNTIME
val arr = shortArrayOf(10, 20, 30, 40)
fun foo(xs: Any): String {
if (xs !is ShortArray) return "not a ShortArray"
val s = StringBuilder()
for ((index, x) in xs.withIndex()) {
s.append("$index:$x;")
}
return s.toString()
}
fun box(): String {
val ss = foo(arr)
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -0,0 +1,12 @@
// WITH_RUNTIME
val arr = shortArrayOf(10, 20, 30, 40)
fun box(): String {
val s = StringBuilder()
for ((index, x) in arr.withIndex()) {
s.append("$index:$x;")
}
val ss = s.toString()
return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'"
}
@@ -5240,12 +5240,48 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("forInByteArrayWithIndexWithSmartCast.kt")
public void testForInByteArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInByteArrrayWithIndex.kt")
public void testForInByteArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInEmptyArrrayWithIndex.kt")
public void testForInEmptyArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndex.kt")
public void testForInGenericArrayOfIntsWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndexWithSmartCast.kt")
public void testForInGenericArrayOfIntsWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayWithIndex.kt")
public void testForInGenericArrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrayWithIndexWithSmartCast.kt")
public void testForInIntArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrrayWithIndex.kt")
public void testForInIntArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt");
@@ -5257,6 +5293,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrayWithIndexWithSmartCast.kt")
public void testForInShortArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrrayWithIndex.kt")
public void testForInShortArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrrayWithIndex.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex")
@@ -5240,12 +5240,48 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("forInByteArrayWithIndexWithSmartCast.kt")
public void testForInByteArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInByteArrrayWithIndex.kt")
public void testForInByteArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInEmptyArrrayWithIndex.kt")
public void testForInEmptyArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndex.kt")
public void testForInGenericArrayOfIntsWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndexWithSmartCast.kt")
public void testForInGenericArrayOfIntsWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayWithIndex.kt")
public void testForInGenericArrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrayWithIndexWithSmartCast.kt")
public void testForInIntArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrrayWithIndex.kt")
public void testForInIntArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt");
@@ -5257,6 +5293,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrayWithIndexWithSmartCast.kt")
public void testForInShortArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrrayWithIndex.kt")
public void testForInShortArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrrayWithIndex.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex")
@@ -5240,12 +5240,48 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName);
}
@TestMetadata("forInByteArrayWithIndexWithSmartCast.kt")
public void testForInByteArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInByteArrrayWithIndex.kt")
public void testForInByteArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInEmptyArrrayWithIndex.kt")
public void testForInEmptyArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndex.kt")
public void testForInGenericArrayOfIntsWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndexWithSmartCast.kt")
public void testForInGenericArrayOfIntsWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayWithIndex.kt")
public void testForInGenericArrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrayWithIndexWithSmartCast.kt")
public void testForInIntArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrrayWithIndex.kt")
public void testForInIntArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt");
@@ -5257,6 +5293,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrayWithIndexWithSmartCast.kt")
public void testForInShortArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrrayWithIndex.kt")
public void testForInShortArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrrayWithIndex.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex")
@@ -5828,12 +5828,48 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("forInByteArrayWithIndexWithSmartCast.kt")
public void testForInByteArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInByteArrrayWithIndex.kt")
public void testForInByteArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInByteArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInEmptyArrrayWithIndex.kt")
public void testForInEmptyArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndex.kt")
public void testForInGenericArrayOfIntsWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayOfIntsWithIndexWithSmartCast.kt")
public void testForInGenericArrayOfIntsWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayOfIntsWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInGenericArrayWithIndex.kt")
public void testForInGenericArrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInGenericArrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrayWithIndexWithSmartCast.kt")
public void testForInIntArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInIntArrrayWithIndex.kt")
public void testForInIntArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt");
@@ -5845,6 +5881,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrayWithIndexWithSmartCast.kt")
public void testForInShortArrayWithIndexWithSmartCast() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrayWithIndexWithSmartCast.kt");
doTest(fileName);
}
@TestMetadata("forInShortArrrayWithIndex.kt")
public void testForInShortArrrayWithIndex() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInShortArrrayWithIndex.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex")