KT-13023 Char operations throw ClassCastException for boxed Chars
Char is not a Number, so we can't use the same coercion strategy for Char members, since it doesn't work for boxed Chars.
This commit is contained in:
@@ -32,14 +32,25 @@ class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
|||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val returnType = method.returnType
|
val returnType = method.returnType
|
||||||
assert(method.getValueParameters().size == 1)
|
assert(method.getValueParameters().size == 1)
|
||||||
val operandType = numberFunctionOperandType(returnType)
|
|
||||||
val paramType = if (shift()) Type.INT_TYPE else operandType
|
|
||||||
|
|
||||||
return createBinaryIntrinsicCallable(returnType, paramType, operandType) {
|
val arg0Type: Type
|
||||||
v ->
|
val arg1Type: Type
|
||||||
v.visitInsn(returnType.getOpcode(opcode))
|
val intermediateResultType: Type
|
||||||
if (operandType != returnType)
|
|
||||||
StackValue.coerce(operandType, returnType, v)
|
if (method.owner != Type.CHAR_TYPE) {
|
||||||
|
intermediateResultType = numberFunctionOperandType(returnType)
|
||||||
|
arg0Type = intermediateResultType
|
||||||
|
arg1Type = if (shift()) Type.INT_TYPE else arg0Type
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arg0Type = Type.CHAR_TYPE
|
||||||
|
arg1Type = method.getValueParameters()[0].asmType
|
||||||
|
intermediateResultType = numberFunctionOperandType(returnType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return createBinaryIntrinsicCallable(returnType, arg1Type, arg0Type) { v ->
|
||||||
|
v.visitInsn(returnType.getOpcode(opcode))
|
||||||
|
StackValue.coerce(intermediateResultType, returnType, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val b = 'b'
|
||||||
|
val c = 'c'
|
||||||
|
assertEquals('c', b + 1)
|
||||||
|
assertEquals('a', b - 1)
|
||||||
|
assertEquals(1, c - b)
|
||||||
|
|
||||||
|
val list = listOf('b', 'a')
|
||||||
|
assertEquals('c', list[0] + 1)
|
||||||
|
assertEquals('a', list[0] - 1)
|
||||||
|
assertEquals(1, list[0] - list[1])
|
||||||
|
assertEquals(1, list[0] - 'a')
|
||||||
|
assertEquals(1, 'b' - list[1])
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -9766,6 +9766,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt13023.kt")
|
||||||
|
public void testKt13023() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/primitiveTypes/kt13023.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt1508.kt")
|
@TestMetadata("kt1508.kt")
|
||||||
public void testKt1508() throws Exception {
|
public void testKt1508() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/primitiveTypes/kt1508.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/primitiveTypes/kt1508.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user