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:
Dmitry Petrov
2016-07-07 16:23:42 +03:00
parent 2ccb0caa6c
commit b0edec8449
3 changed files with 44 additions and 7 deletions
@@ -32,14 +32,25 @@ class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
val returnType = method.returnType
assert(method.getValueParameters().size == 1)
val operandType = numberFunctionOperandType(returnType)
val paramType = if (shift()) Type.INT_TYPE else operandType
return createBinaryIntrinsicCallable(returnType, paramType, operandType) {
v ->
v.visitInsn(returnType.getOpcode(opcode))
if (operandType != returnType)
StackValue.coerce(operandType, returnType, v)
val arg0Type: Type
val arg1Type: Type
val intermediateResultType: Type
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)
}
}
}
+20
View File
@@ -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);
}
@TestMetadata("kt13023.kt")
public void testKt13023() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/primitiveTypes/kt13023.kt");
doTest(fileName);
}
@TestMetadata("kt1508.kt")
public void testKt1508() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/primitiveTypes/kt1508.kt");