Fix CCE in generated code that happens when comparing boxed chars
The problem was that when obtaining char from the wrapper, codegen used int as expected type that led to a ClassCastException: java.lang.Character cannot be cast to java.lang.Number The solution is using coercion to chars, it's still correct, because of implicit widening coercion in JVM from C to I #KT-15105 Fixed
This commit is contained in:
@@ -770,6 +770,7 @@ public class AsmUtil {
|
||||
if (left == Type.DOUBLE_TYPE || right == Type.DOUBLE_TYPE) return Type.DOUBLE_TYPE;
|
||||
if (left == Type.FLOAT_TYPE || right == Type.FLOAT_TYPE) return Type.FLOAT_TYPE;
|
||||
if (left == Type.LONG_TYPE || right == Type.LONG_TYPE) return Type.LONG_TYPE;
|
||||
if (left == Type.CHAR_TYPE || right == Type.CHAR_TYPE) return Type.CHAR_TYPE;
|
||||
return Type.INT_TYPE;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
class CompareTo : IntrinsicMethod() {
|
||||
private fun genInvoke(type: Type?, v: InstructionAdapter) {
|
||||
when (type) {
|
||||
Type.INT_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false)
|
||||
Type.INT_TYPE, Type.CHAR_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false)
|
||||
Type.LONG_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(JJ)I", false)
|
||||
Type.FLOAT_TYPE -> v.invokestatic("java/lang/Float", "compare", "(FF)I", false)
|
||||
Type.DOUBLE_TYPE -> v.invokestatic("java/lang/Double", "compare", "(DD)I", false)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
fun <T> id(x: T) = x
|
||||
|
||||
fun box(): String {
|
||||
if (id('a') > id('b')) return "fail 1"
|
||||
if (id('a') >= id('b')) return "fail 2"
|
||||
if (id('b') < id('a')) return "fail 3"
|
||||
if (id('b') <= id('a')) return "fail 4"
|
||||
|
||||
val x = id('a').compareTo('b')
|
||||
if (x != -1) return "fail 5"
|
||||
|
||||
val y = id('b').compareTo('a')
|
||||
if (y != 1) return "fail 6"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@kotlin.Metadata
|
||||
public final class CompareBoxedCharsKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method id(p0: java.lang.Object): java.lang.Object
|
||||
}
|
||||
+6
@@ -785,6 +785,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compareBoxedChars.kt")
|
||||
public void testCompareBoxedChars() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/compareBoxedChars.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compareWithBoxedDouble.kt")
|
||||
public void testCompareWithBoxedDouble() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/compareWithBoxedDouble.kt");
|
||||
|
||||
@@ -785,6 +785,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compareBoxedChars.kt")
|
||||
public void testCompareBoxedChars() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/compareBoxedChars.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compareWithBoxedDouble.kt")
|
||||
public void testCompareWithBoxedDouble() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/compareWithBoxedDouble.kt");
|
||||
|
||||
@@ -977,6 +977,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compareBoxedChars.kt")
|
||||
public void testCompareBoxedChars() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/compareBoxedChars.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compareWithBoxedDouble.kt")
|
||||
public void testCompareWithBoxedDouble() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/compareWithBoxedDouble.kt");
|
||||
|
||||
Reference in New Issue
Block a user