diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/BinaryOp.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/BinaryOp.kt index 8806c6cad2c..8a3a576387e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/BinaryOp.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/BinaryOp.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.org.objectweb.asm.Opcodes.ISHL import org.jetbrains.org.objectweb.asm.Opcodes.ISHR import org.jetbrains.org.objectweb.asm.Opcodes.IUSHR @@ -35,7 +36,10 @@ public class BinaryOp(private val opcode: Int) : IntrinsicMethod() { val paramType = if (shift()) Type.INT_TYPE else operandType return createBinaryIntrinsicCallable(returnType, paramType, operandType) { - v -> v.visitInsn(returnType.getOpcode(opcode)) + v -> + v.visitInsn(returnType.getOpcode(opcode)); + if (operandType != returnType) + StackValue.coerce(operandType, returnType, v) } } } diff --git a/compiler/testData/codegen/box/binaryOp/longOverflow.kt b/compiler/testData/codegen/box/binaryOp/longOverflow.kt deleted file mode 100644 index 9f7a9f6bd4d..00000000000 --- a/compiler/testData/codegen/box/binaryOp/longOverflow.kt +++ /dev/null @@ -1,5 +0,0 @@ -fun box(): String { - val a: Long = 2147483647 + 1 - if (a != -2147483648L) return "fail: in this case we should add to ints and than cast the result to long - overflow expected" - return "OK" -} \ No newline at end of file diff --git a/compiler/testData/codegen/box/binaryOp/overflowChar.kt b/compiler/testData/codegen/box/binaryOp/overflowChar.kt new file mode 100644 index 00000000000..0f06f4969fd --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/overflowChar.kt @@ -0,0 +1,10 @@ +fun box(): String { + val c1: Char = 0.toChar() + val c2 = c1 - 1 + if (c2 < c1) return "fail: 0.toChar() - 1 should overflow to positive." + + val c3 = c2 + 1 + if (c3 > c2) return "fail: FFFF.toChar() + 1 should overflow to zero." + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/binaryOp/overflowInt.kt b/compiler/testData/codegen/box/binaryOp/overflowInt.kt new file mode 100644 index 00000000000..4d5b899987f --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/overflowInt.kt @@ -0,0 +1,11 @@ +fun box(): String { + val i1: Int = Int.MAX_VALUE + val i2 = i1 + 1 + if (i2 > i1) return "fail: Int.MAX_VALUE + 1 should overflow to negative." + + val i3: Int = Int.MIN_VALUE + val i4 = i3 - 1 + if (i4 < i3) return "fail: Int.MIN_VALUE - 1 should overflow to positive." + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/binaryOp/overflowLong.kt b/compiler/testData/codegen/box/binaryOp/overflowLong.kt new file mode 100644 index 00000000000..28d37ab1c12 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/overflowLong.kt @@ -0,0 +1,14 @@ +fun box(): String { + val a: Long = 2147483647 + 1 + if (a != -2147483648L) return "fail: in this case we should add to ints and than cast the result to long - overflow expected" + + val l1 = Long.MAX_VALUE + val l2 = l1 + 1 + if (l2 > l1) return "fail: Long.MAX_VALUE + 1 should overflow to negative." + + val l3 = Long.MIN_VALUE + val l4 = l3 - 1 + if (l4 < l3) return "fail: Long.MIN_VALUE - 1 should overflow to positive." + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 875ede44b80..e3921f3bf3f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -322,9 +322,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } - @TestMetadata("longOverflow.kt") - public void testLongOverflow() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/longOverflow.kt"); + @TestMetadata("overflowChar.kt") + public void testOverflowChar() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/overflowChar.kt"); + doTest(fileName); + } + + @TestMetadata("overflowInt.kt") + public void testOverflowInt() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/overflowInt.kt"); + doTest(fileName); + } + + @TestMetadata("overflowLong.kt") + public void testOverflowLong() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/binaryOp/overflowLong.kt"); doTest(fileName); } }