Ensure type of a stack value is coerced to the expected return type after the binary operation instruction with the different return type.

This commit is contained in:
Ilya Gorbunov
2015-07-11 16:09:22 +03:00
parent f7ccb3819e
commit 4ad6a8e301
6 changed files with 55 additions and 9 deletions
@@ -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)
}
}
}
@@ -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"
}
+10
View File
@@ -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"
}
+11
View File
@@ -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"
}
+14
View File
@@ -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"
}
@@ -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);
}
}