Use specified comparison generator for chars in optimized ranges
Otherwise if Char value is a result of some erased generic call, coercing it to I (primitive int) causes CCE at run-time. #KT-23104 Fixed Target versions 1.2.40
This commit is contained in:
+7
-6
@@ -35,7 +35,8 @@ interface ComparisonGenerator {
|
||||
|
||||
fun getComparisonGeneratorForPrimitiveType(type: Type): ComparisonGenerator =
|
||||
when {
|
||||
type.isRepresentedAsPrimitiveInt() -> IntComparisonGenerator
|
||||
type == Type.CHAR_TYPE -> CharComparisonGenerator
|
||||
type.isPrimitiveIntOrCoercible() -> IntComparisonGenerator
|
||||
type == Type.LONG_TYPE -> LongComparisonGenerator
|
||||
type == Type.FLOAT_TYPE -> FloatComparisonGenerator
|
||||
type == Type.DOUBLE_TYPE -> DoubleComparisonGenerator
|
||||
@@ -61,11 +62,11 @@ fun getComparisonGeneratorForRangeContainsCall(
|
||||
asmElementType == asmValueParameterType ->
|
||||
getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
|
||||
asmElementType.isRepresentedAsPrimitiveInt() && asmValueParameterType.isRepresentedAsPrimitiveInt() ->
|
||||
asmElementType.isPrimitiveIntOrCoercible() && asmValueParameterType.isPrimitiveIntOrCoercible() ->
|
||||
IntComparisonGenerator
|
||||
|
||||
asmElementType.isRepresentedAsPrimitiveInt() && asmValueParameterType == Type.LONG_TYPE ||
|
||||
asmValueParameterType.isRepresentedAsPrimitiveInt() && asmElementType == Type.LONG_TYPE ->
|
||||
asmElementType.isPrimitiveIntOrCoercible() && asmValueParameterType == Type.LONG_TYPE ||
|
||||
asmValueParameterType.isPrimitiveIntOrCoercible() && asmElementType == Type.LONG_TYPE ->
|
||||
LongComparisonGenerator
|
||||
|
||||
asmElementType == Type.FLOAT_TYPE && asmValueParameterType == Type.DOUBLE_TYPE ||
|
||||
@@ -76,5 +77,5 @@ fun getComparisonGeneratorForRangeContainsCall(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Type.isRepresentedAsPrimitiveInt() =
|
||||
this == Type.INT_TYPE || this == Type.SHORT_TYPE || this == Type.BYTE_TYPE || this == Type.CHAR_TYPE
|
||||
private fun Type.isPrimitiveIntOrCoercible() =
|
||||
this == Type.INT_TYPE || this == Type.SHORT_TYPE || this == Type.BYTE_TYPE
|
||||
+6
-4
@@ -20,9 +20,7 @@ import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
object IntComparisonGenerator : ComparisonGenerator {
|
||||
override val comparedType: Type = Type.INT_TYPE
|
||||
|
||||
abstract class IntegerComparisonGenerator(override val comparedType: Type) : ComparisonGenerator {
|
||||
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
||||
v.ificmpge(label)
|
||||
}
|
||||
@@ -38,4 +36,8 @@ object IntComparisonGenerator : ComparisonGenerator {
|
||||
override fun jumpIfLess(v: InstructionAdapter, label: Label) {
|
||||
v.ificmplt(label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object IntComparisonGenerator : IntegerComparisonGenerator(Type.INT_TYPE)
|
||||
|
||||
object CharComparisonGenerator : IntegerComparisonGenerator(Type.CHAR_TYPE)
|
||||
@@ -0,0 +1,7 @@
|
||||
class Cell<T>(val value: T)
|
||||
|
||||
fun box(): String =
|
||||
if (Cell('a').value in 'a'..'z')
|
||||
"OK"
|
||||
else
|
||||
"fail"
|
||||
Generated
+6
@@ -15398,6 +15398,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericCharInRangeLiteral.kt")
|
||||
public void testGenericCharInRangeLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/genericCharInRangeLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inArray.kt")
|
||||
public void testInArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt");
|
||||
|
||||
+6
@@ -15398,6 +15398,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericCharInRangeLiteral.kt")
|
||||
public void testGenericCharInRangeLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/genericCharInRangeLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inArray.kt")
|
||||
public void testInArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt");
|
||||
|
||||
+6
@@ -15398,6 +15398,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericCharInRangeLiteral.kt")
|
||||
public void testGenericCharInRangeLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/genericCharInRangeLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inArray.kt")
|
||||
public void testInArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt");
|
||||
|
||||
+6
@@ -16658,6 +16658,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericCharInRangeLiteral.kt")
|
||||
public void testGenericCharInRangeLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/genericCharInRangeLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inArray.kt")
|
||||
public void testInArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt");
|
||||
|
||||
Reference in New Issue
Block a user