From 69ed9bc47aa86639ca122063aa6872596e7dcbd9 Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Mon, 9 Dec 2013 16:50:12 +0400 Subject: [PATCH] Do not cast arguments of binary operation to expected type for byte and short --- .../org/jetbrains/jet/codegen/AsmUtil.java | 8 ++ .../jet/codegen/ExpressionCodegen.java | 31 +++---- .../org/jetbrains/jet/codegen/StackValue.java | 24 ++++-- .../jet/codegen/intrinsics/BinaryOp.java | 20 ++--- .../jet/codegen/intrinsics/Increment.java | 5 +- .../jetbrains/jet/codegen/intrinsics/Inv.java | 8 +- .../jet/codegen/intrinsics/UnaryMinus.java | 15 ++-- .../jet/codegen/intrinsics/UnaryPlus.java | 5 +- .../testData/codegen/box/binaryOp/call.kt | 17 ++++ .../codegen/box/binaryOp/callNullable.kt | 17 ++++ .../codegen/box/binaryOp/infixCall.kt | 17 ++++ .../codegen/box/binaryOp/infixCallNullable.kt | 17 ++++ .../codegen/box/binaryOp/intrinsic.kt | 17 ++++ .../codegen/box/binaryOp/intrinsicNullable.kt | 17 ++++ .../codegen/box/binaryOp/longOverflow.kt | 5 ++ compiler/testData/codegen/box/unaryOp/call.kt | 17 ++++ .../codegen/box/unaryOp/callNullable.kt | 17 ++++ .../testData/codegen/box/unaryOp/intrinsic.kt | 17 ++++ .../codegen/box/unaryOp/intrinsicNullable.kt | 17 ++++ .../codegen/box/unaryOp/longOverflow.kt | 5 ++ .../codegen/bytecodeText/constants/byte.kt | 3 + .../codegen/bytecodeText/constants/short.kt | 3 + .../codegen/BytecodeTextTestGenerated.java | 21 ++++- .../BlackBoxCodegenTestGenerated.java | 80 ++++++++++++++++++- 24 files changed, 351 insertions(+), 52 deletions(-) create mode 100644 compiler/testData/codegen/box/binaryOp/call.kt create mode 100644 compiler/testData/codegen/box/binaryOp/callNullable.kt create mode 100644 compiler/testData/codegen/box/binaryOp/infixCall.kt create mode 100644 compiler/testData/codegen/box/binaryOp/infixCallNullable.kt create mode 100644 compiler/testData/codegen/box/binaryOp/intrinsic.kt create mode 100644 compiler/testData/codegen/box/binaryOp/intrinsicNullable.kt create mode 100644 compiler/testData/codegen/box/binaryOp/longOverflow.kt create mode 100644 compiler/testData/codegen/box/unaryOp/call.kt create mode 100644 compiler/testData/codegen/box/unaryOp/callNullable.kt create mode 100644 compiler/testData/codegen/box/unaryOp/intrinsic.kt create mode 100644 compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt create mode 100644 compiler/testData/codegen/box/unaryOp/longOverflow.kt create mode 100644 compiler/testData/codegen/bytecodeText/constants/byte.kt create mode 100644 compiler/testData/codegen/bytecodeText/constants/short.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 94959cd6f0d..3dd88139b2e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -631,6 +631,14 @@ public class AsmUtil { return Type.INT_TYPE; } + @NotNull + public static Type numberFunctionOperandType(@NotNull Type expectedType) { + if (expectedType == Type.SHORT_TYPE || expectedType == Type.BYTE_TYPE) { + return Type.INT_TYPE; + } + return expectedType; + } + public static void pop(@NotNull InstructionAdapter v, @NotNull Type type) { if (type.getSize() == 2) { v.pop2(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index a1a0e75c470..6a4a61f474e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -36,7 +36,7 @@ import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.context.*; -import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; +import org.jetbrains.jet.codegen.intrinsics.*; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; @@ -1652,8 +1652,8 @@ public class ExpressionCodegen extends JetVisitor implem IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor); if (intrinsic != null) { - Type expectedType = expressionType(expression); - return intrinsic.generate(this, v, expectedType, expression, Collections.emptyList(), receiver, state); + Type returnType = typeMapper.mapType(memberDescriptor.getReturnType()); + return intrinsic.generate(this, v, returnType, expression, Collections.emptyList(), receiver, state); } } @@ -2030,14 +2030,12 @@ public class ExpressionCodegen extends JetVisitor implem for (ValueArgument argument : call.getValueArguments()) { args.add(argument.getArgumentExpression()); } - JetType type = resolvedCall.getResultingDescriptor().getReturnType(); - assert type != null; - Type callType = typeMapper.mapType(type); - Type exprType = asmTypeOrVoid(type); - StackValue stackValue = intrinsic.generate(this, v, callType, call.getCallElement(), args, receiver, state); - stackValue.put(exprType, v); - return StackValue.onStack(exprType); + Type returnType = typeMapper.mapType(resolvedCall.getResultingDescriptor().getReturnType()); + + StackValue stackValue = intrinsic.generate(this, v, returnType, call.getCallElement(), args, receiver, state); + stackValue.put(returnType, v); + return StackValue.onStack(returnType); } } @@ -2682,7 +2680,8 @@ public class ExpressionCodegen extends JetVisitor implem Callable callable = resolveToCallable((FunctionDescriptor) op, false); if (callable instanceof IntrinsicMethod) { IntrinsicMethod intrinsic = (IntrinsicMethod) callable; - return intrinsic.generate(this, v, expressionType(expression), expression, + Type returnType = typeMapper.mapType(resolvedCall.getResultingDescriptor().getReturnType()); + return intrinsic.generate(this, v, returnType, expression, Arrays.asList(expression.getLeft(), expression.getRight()), receiver, state); } else { @@ -2929,10 +2928,11 @@ public class ExpressionCodegen extends JetVisitor implem //noinspection NullableProblems JetExpression right = expression.getRight(); assert right != null; - StackValue stackValue = intrinsic.generate(this, v, lhsType, expression, + Type returnType = typeMapper.mapType(((FunctionDescriptor) op).getReturnType()); + StackValue stackValue = intrinsic.generate(this, v, returnType, expression, Arrays.asList(right), StackValue.onStack(lhsType), state); - value.store(stackValue.type, v); + value.store(lhsType, v); } else { callAugAssignMethod(expression, (CallableMethod) callable, lhsType, true); @@ -3018,7 +3018,8 @@ public class ExpressionCodegen extends JetVisitor implem if (callable instanceof IntrinsicMethod) { IntrinsicMethod intrinsic = (IntrinsicMethod) callable; //noinspection ConstantConditions - return intrinsic.generate(this, v, expressionType(expression), expression, + Type returnType = typeMapper.mapType(((FunctionDescriptor) op).getReturnType()); + return intrinsic.generate(this, v, returnType, expression, Arrays.asList(expression.getBaseExpression()), receiver, state); } else { @@ -3589,7 +3590,7 @@ The "returned" value of try expression with no finally is either the last expres DeclarationDescriptor descriptor = rightType.getConstructor().getDeclarationDescriptor(); if (descriptor instanceof ClassDescriptor || descriptor instanceof TypeParameterDescriptor) { StackValue value = genQualified(receiver, left); - value.put(boxType(value.type), v); + value.put(boxType(rightTypeAsm), v); if (opToken != JetTokens.AS_SAFE) { if (!CodegenUtil.isNullableType(rightType)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 4a4cb7af35f..c6597d3155a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -40,6 +40,11 @@ import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; public abstract class StackValue { + + private static final String NULLABLE_BYTE_TYPE_NAME = "java/lang/Byte"; + private static final String NULLABLE_SHORT_TYPE_NAME = "java/lang/Short"; + private static final String NULLABLE_LONG_TYPE_NAME = "java/lang/Long"; + @NotNull public final Type type; @@ -154,8 +159,17 @@ public abstract class StackValue { } private static void box(Type type, Type toType, InstructionAdapter v) { - // TODO handle toType correctly - if (type == Type.INT_TYPE || (isIntPrimitive(type) && toType.getInternalName().equals("java/lang/Integer"))) { + if (type == Type.BYTE_TYPE || toType.getInternalName().equals(NULLABLE_BYTE_TYPE_NAME) && type == Type.INT_TYPE) { + v.invokestatic(NULLABLE_BYTE_TYPE_NAME, "valueOf", "(B)L" + NULLABLE_BYTE_TYPE_NAME + ";"); + } + else if (type == Type.SHORT_TYPE || toType.getInternalName().equals(NULLABLE_SHORT_TYPE_NAME) && type == Type.INT_TYPE) { + v.invokestatic(NULLABLE_SHORT_TYPE_NAME, "valueOf", "(S)L" + NULLABLE_SHORT_TYPE_NAME + ";"); + } + else if (toType.getInternalName().equals(NULLABLE_LONG_TYPE_NAME) && type == Type.INT_TYPE) { + v.cast(type, Type.LONG_TYPE); + v.invokestatic(NULLABLE_LONG_TYPE_NAME, "valueOf", "(J)L" + NULLABLE_LONG_TYPE_NAME +";"); + } + else if (type == Type.INT_TYPE) { v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else if (type == Type.BOOLEAN_TYPE) { @@ -164,15 +178,9 @@ public abstract class StackValue { else if (type == Type.CHAR_TYPE) { v.invokestatic("java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); } - else if (type == Type.SHORT_TYPE) { - v.invokestatic("java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); - } else if (type == Type.LONG_TYPE) { v.invokestatic("java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); } - else if (type == Type.BYTE_TYPE) { - v.invokestatic("java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); - } else if (type == Type.FLOAT_TYPE) { v.invokestatic("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java index 895c234ba4b..a8eb33e5100 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java @@ -29,6 +29,7 @@ import java.util.List; import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.AsmUtil.boxType; +import static org.jetbrains.jet.codegen.AsmUtil.numberFunctionOperandType; import static org.jetbrains.jet.codegen.AsmUtil.unboxType; public class BinaryOp implements IntrinsicMethod { @@ -48,26 +49,25 @@ public class BinaryOp implements IntrinsicMethod { StackValue receiver, @NotNull GenerationState state ) { + boolean nullable = expectedType.getSort() == Type.OBJECT; - if (nullable) { - expectedType = unboxType(expectedType); - } + assert !nullable : "Return type of BinaryOp intrinsic should be of primitive type : " + expectedType; + + Type operandType = numberFunctionOperandType(expectedType); + if (arguments.size() == 1) { // Intrinsic is called as an ordinary function if (receiver != null) { - receiver.put(expectedType, v); + receiver.put(operandType, v); } - codegen.gen(arguments.get(0), shift() ? Type.INT_TYPE : expectedType); + codegen.gen(arguments.get(0), shift() ? Type.INT_TYPE : operandType); } else { - codegen.gen(arguments.get(0), expectedType); - codegen.gen(arguments.get(1), shift() ? Type.INT_TYPE : expectedType); + codegen.gen(arguments.get(0), operandType); + codegen.gen(arguments.get(1), shift() ? Type.INT_TYPE : operandType); } v.visitInsn(expectedType.getOpcode(opcode)); - if (nullable) { - StackValue.onStack(expectedType).put(expectedType = boxType(expectedType), v); - } return StackValue.onStack(expectedType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index f358295e8ef..76fc8cd71c0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -50,9 +50,8 @@ public class Increment implements IntrinsicMethod { @NotNull GenerationState state ) { boolean nullable = expectedType.getSort() == Type.OBJECT; - if (nullable) { - expectedType = unboxType(expectedType); - } + assert !nullable : "Return type of Increment intrinsic should be of primitive type : " + expectedType; + if (arguments.size() > 0) { JetExpression operand = arguments.get(0); while (operand instanceof JetParenthesizedExpression) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java index 6e2da0bf0fa..2b3fa41dafa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.numberFunctionOperandType; import static org.jetbrains.jet.codegen.AsmUtil.unboxType; public class Inv implements IntrinsicMethod { @@ -41,10 +42,9 @@ public class Inv implements IntrinsicMethod { @NotNull GenerationState state ) { boolean nullable = expectedType.getSort() == Type.OBJECT; - if (nullable) { - expectedType = unboxType(expectedType); - } - receiver.put(expectedType, v); + assert !nullable : "Return type of Inv intrinsic should be of primitive type : " + expectedType; + + receiver.put(numberFunctionOperandType(expectedType), v); if (expectedType == Type.LONG_TYPE) { v.lconst(-1L); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java index 849b4549708..52029eee0b1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; import static org.jetbrains.jet.codegen.AsmUtil.genNegate; +import static org.jetbrains.jet.codegen.AsmUtil.numberFunctionOperandType; import static org.jetbrains.jet.codegen.AsmUtil.unboxType; public class UnaryMinus implements IntrinsicMethod { @@ -42,16 +43,16 @@ public class UnaryMinus implements IntrinsicMethod { @NotNull GenerationState state ) { boolean nullable = expectedType.getSort() == Type.OBJECT; - if (nullable) { - expectedType = unboxType(expectedType); - } + assert !nullable : "Return type of UnaryMinus intrinsic should be of primitive type : " + expectedType; + + Type operandType = numberFunctionOperandType(expectedType); + if (arguments.size() == 1) { - codegen.gen(arguments.get(0), expectedType); + codegen.gen(arguments.get(0), operandType); } else { - receiver.put(expectedType, v); + receiver.put(operandType, v); } - StackValue.coerce(genNegate(expectedType, v), expectedType, v); - return StackValue.onStack(expectedType); + return StackValue.onStack(genNegate(expectedType, v)); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java index 778e238c83b..a134169d3a7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java @@ -42,9 +42,8 @@ public class UnaryPlus implements IntrinsicMethod { @NotNull GenerationState state ) { boolean nullable = expectedType.getSort() == Type.OBJECT; - if (nullable) { - expectedType = unboxType(expectedType); - } + assert !nullable : "Return type of UnaryPlus intrinsic should be of primitive type : " + expectedType; + if (receiver != null && receiver != StackValue.none()) { receiver.put(expectedType, v); } diff --git a/compiler/testData/codegen/box/binaryOp/call.kt b/compiler/testData/codegen/box/binaryOp/call.kt new file mode 100644 index 00000000000..c7a2752f4bb --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/call.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = 1.plus(1) + val a2: Short = 1.plus(1) + val a3: Int = 1.plus(1) + val a4: Long = 1.plus(1) + val a5: Double = 1.0.plus(1) + val a6: Float = 1f.plus(1) + + if (a1 != 2.toByte()) return "fail 1" + if (a2 != 2.toShort()) return "fail 2" + if (a3 != 2) return "fail 3" + if (a4 != 2L) return "fail 4" + if (a5 != 2.0) return "fail 5" + if (a6 != 2f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/binaryOp/callNullable.kt b/compiler/testData/codegen/box/binaryOp/callNullable.kt new file mode 100644 index 00000000000..802bef63e31 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/callNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = 1.plus(1) + val a2: Short? = 1.plus(1) + val a3: Int? = 1.plus(1) + val a4: Long? = 1.plus(1) + val a5: Double? = 1.0.plus(1) + val a6: Float? = 1f.plus(1) + + if (a1!! != 2.toByte()) return "fail 1" + if (a2!! != 2.toShort()) return "fail 2" + if (a3!! != 2) return "fail 3" + if (a4!! != 2L) return "fail 4" + if (a5!! != 2.0) return "fail 5" + if (a6!! != 2f) return "fail 6" + + return "OK" +} diff --git a/compiler/testData/codegen/box/binaryOp/infixCall.kt b/compiler/testData/codegen/box/binaryOp/infixCall.kt new file mode 100644 index 00000000000..f8f688298c4 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/infixCall.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = 1 plus 1 + val a2: Short = 1 plus 1 + val a3: Int = 1 plus 1 + val a4: Long = 1 plus 1 + val a5: Double = 1.0 plus 1 + val a6: Float = 1f plus 1 + + if (a1 != 2.toByte()) return "fail 1" + if (a2 != 2.toShort()) return "fail 2" + if (a3 != 2) return "fail 3" + if (a4 != 2L) return "fail 4" + if (a5 != 2.0) return "fail 5" + if (a6 != 2f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/binaryOp/infixCallNullable.kt b/compiler/testData/codegen/box/binaryOp/infixCallNullable.kt new file mode 100644 index 00000000000..4a8ed98d307 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/infixCallNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = 1 plus 1 + val a2: Short? = 1 plus 1 + val a3: Int? = 1 plus 1 + val a4: Long? = 1 plus 1 + val a5: Double? = 1.0 plus 1 + val a6: Float? = 1f plus 1 + + if (a1!! != 2.toByte()) return "fail 1" + if (a2!! != 2.toShort()) return "fail 2" + if (a3!! != 2) return "fail 3" + if (a4!! != 2L) return "fail 4" + if (a5!! != 2.0) return "fail 5" + if (a6!! != 2f) return "fail 6" + + return "OK" +} diff --git a/compiler/testData/codegen/box/binaryOp/intrinsic.kt b/compiler/testData/codegen/box/binaryOp/intrinsic.kt new file mode 100644 index 00000000000..cd39565e450 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/intrinsic.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = 1 + 1 + val a2: Short = 1 + 1 + val a3: Int = 1 + 1 + val a4: Long = 1 + 1 + val a5: Double = 1.0 + 1 + val a6: Float = 1f + 1 + + if (a1 != 2.toByte()) return "fail 1" + if (a2 != 2.toShort()) return "fail 2" + if (a3 != 2) return "fail 3" + if (a4 != 2L) return "fail 4" + if (a5 != 2.0) return "fail 5" + if (a6 != 2f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/binaryOp/intrinsicNullable.kt b/compiler/testData/codegen/box/binaryOp/intrinsicNullable.kt new file mode 100644 index 00000000000..75288bc5be8 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/intrinsicNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = 1 + 1 + val a2: Short? = 1 + 1 + val a3: Int? = 1 + 1 + val a4: Long? = 1 + 1 + val a5: Double? = 1.0 + 1 + val a6: Float? = 1f + 1 + + if (a1!! != 2.toByte()) return "fail 1" + if (a2!! != 2.toShort()) return "fail 2" + if (a3!! != 2) return "fail 3" + if (a4!! != 2L) return "fail 4" + if (a5!! != 2.0) return "fail 5" + if (a6!! != 2f) return "fail 6" + + return "OK" +} diff --git a/compiler/testData/codegen/box/binaryOp/longOverflow.kt b/compiler/testData/codegen/box/binaryOp/longOverflow.kt new file mode 100644 index 00000000000..9f7a9f6bd4d --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/longOverflow.kt @@ -0,0 +1,5 @@ +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/unaryOp/call.kt b/compiler/testData/codegen/box/unaryOp/call.kt new file mode 100644 index 00000000000..1431554f7b8 --- /dev/null +++ b/compiler/testData/codegen/box/unaryOp/call.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = 1.minus() + val a2: Short = 1.minus() + val a3: Int = 1.minus() + val a4: Long = 1.minus() + val a5: Double = 1.0.minus() + val a6: Float = 1f.minus() + + if (a1 != -1.toByte()) return "fail 1" + if (a2 != -1.toShort()) return "fail -1" + if (a3 != -1) return "fail 3" + if (a4 != -1L) return "fail 4" + if (a5 != -1.0) return "fail 5" + if (a6 != -1f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/unaryOp/callNullable.kt b/compiler/testData/codegen/box/unaryOp/callNullable.kt new file mode 100644 index 00000000000..6bfeb00c4cb --- /dev/null +++ b/compiler/testData/codegen/box/unaryOp/callNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = 1.minus() + val a2: Short? = 1.minus() + val a3: Int? = 1.minus() + val a4: Long? = 1.minus() + val a5: Double? = 1.0.minus() + val a6: Float? = 1f.minus() + + if (a1!! != -1.toByte()) return "fail 1" + if (a2!! != -1.toShort()) return "fail 2" + if (a3!! != -1) return "fail 3" + if (a4!! != -1L) return "fail 4" + if (a5!! != -1.0) return "fail 5" + if (a6!! != -1f) return "fail 6" + + return "OK" +} diff --git a/compiler/testData/codegen/box/unaryOp/intrinsic.kt b/compiler/testData/codegen/box/unaryOp/intrinsic.kt new file mode 100644 index 00000000000..e2766c5abe8 --- /dev/null +++ b/compiler/testData/codegen/box/unaryOp/intrinsic.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = -1 + val a2: Short = -1 + val a3: Int = -1 + val a4: Long = -1 + val a5: Double = -1.0 + val a6: Float = -1f + + if (a1 != -1.toByte()) return "fail 1" + if (a2 != -1.toShort()) return "fail 2" + if (a3 != -1) return "fail 3" + if (a4 != -1L) return "fail 4" + if (a5 != -1.0) return "fail 5" + if (a6 != -1f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt b/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt new file mode 100644 index 00000000000..a7756e17247 --- /dev/null +++ b/compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = -1 + val a2: Short? = -1 + val a3: Int? = -1 + val a4: Long? = -1 + val a5: Double? = -1.0 + val a6: Float? = -1f + + if (a1!! != -1.toByte()) return "fail 1" + if (a2!! != -1.toShort()) return "fail 2" + if (a3!! != -1) return "fail 3" + if (a4!! != -1L) return "fail 4" + if (a5!! != -1.0) return "fail 5" + if (a6!! != -1f) return "fail 6" + + return "OK" +} diff --git a/compiler/testData/codegen/box/unaryOp/longOverflow.kt b/compiler/testData/codegen/box/unaryOp/longOverflow.kt new file mode 100644 index 00000000000..d3615f071ea --- /dev/null +++ b/compiler/testData/codegen/box/unaryOp/longOverflow.kt @@ -0,0 +1,5 @@ +fun box(): String { + val a: Long = -(1 shl 31) + 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/bytecodeText/constants/byte.kt b/compiler/testData/codegen/bytecodeText/constants/byte.kt new file mode 100644 index 00000000000..d9f3adca4ff --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/constants/byte.kt @@ -0,0 +1,3 @@ +val a: Byte = 1 + 1 + +// 1 I2B \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/constants/short.kt b/compiler/testData/codegen/bytecodeText/constants/short.kt new file mode 100644 index 00000000000..0d100a76c29 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/constants/short.kt @@ -0,0 +1,3 @@ +val a: Short = 1 + 1 + +// 1 I2S \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/BytecodeTextTestGenerated.java index af4f3ad1a78..5be113df25d 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/BytecodeTextTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.AbstractBytecodeTextTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/bytecodeText") -@InnerTestClasses({BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Statements.class}) +@InnerTestClasses({BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Statements.class}) public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { public void testAllFilesPresentInBytecodeText() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/bytecodeText"), Pattern.compile("^(.+)\\.kt$"), true); @@ -102,6 +102,24 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest("compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt"); } + @TestMetadata("compiler/testData/codegen/bytecodeText/constants") + public static class Constants extends AbstractBytecodeTextTest { + public void testAllFilesPresentInConstants() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/bytecodeText/constants"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("byte.kt") + public void testByte() throws Exception { + doTest("compiler/testData/codegen/bytecodeText/constants/byte.kt"); + } + + @TestMetadata("short.kt") + public void testShort() throws Exception { + doTest("compiler/testData/codegen/bytecodeText/constants/short.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/bytecodeText/directInvoke") public static class DirectInvoke extends AbstractBytecodeTextTest { public void testAllFilesPresentInDirectInvoke() throws Exception { @@ -166,6 +184,7 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { public static Test suite() { TestSuite suite = new TestSuite("BytecodeTextTestGenerated"); suite.addTestSuite(BytecodeTextTestGenerated.class); + suite.addTestSuite(Constants.class); suite.addTestSuite(DirectInvoke.class); suite.addTestSuite(Statements.class); return suite; diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 83ee8ffdf79..8fe7c9c93c1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/box") -@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) +@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBox() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), true); @@ -230,6 +230,49 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } + @TestMetadata("compiler/testData/codegen/box/binaryOp") + public static class BinaryOp extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInBinaryOp() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/binaryOp"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("call.kt") + public void testCall() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/call.kt"); + } + + @TestMetadata("callNullable.kt") + public void testCallNullable() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/callNullable.kt"); + } + + @TestMetadata("infixCall.kt") + public void testInfixCall() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/infixCall.kt"); + } + + @TestMetadata("infixCallNullable.kt") + public void testInfixCallNullable() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/infixCallNullable.kt"); + } + + @TestMetadata("intrinsic.kt") + public void testIntrinsic() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/intrinsic.kt"); + } + + @TestMetadata("intrinsicNullable.kt") + public void testIntrinsicNullable() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/intrinsicNullable.kt"); + } + + @TestMetadata("longOverflow.kt") + public void testLongOverflow() throws Exception { + doTest("compiler/testData/codegen/box/binaryOp/longOverflow.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/box/bridges") public static class Bridges extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBridges() throws Exception { @@ -4786,6 +4829,39 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } + @TestMetadata("compiler/testData/codegen/box/unaryOp") + public static class UnaryOp extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInUnaryOp() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/unaryOp"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("call.kt") + public void testCall() throws Exception { + doTest("compiler/testData/codegen/box/unaryOp/call.kt"); + } + + @TestMetadata("callNullable.kt") + public void testCallNullable() throws Exception { + doTest("compiler/testData/codegen/box/unaryOp/callNullable.kt"); + } + + @TestMetadata("intrinsic.kt") + public void testIntrinsic() throws Exception { + doTest("compiler/testData/codegen/box/unaryOp/intrinsic.kt"); + } + + @TestMetadata("intrinsicNullable.kt") + public void testIntrinsicNullable() throws Exception { + doTest("compiler/testData/codegen/box/unaryOp/intrinsicNullable.kt"); + } + + @TestMetadata("longOverflow.kt") + public void testLongOverflow() throws Exception { + doTest("compiler/testData/codegen/box/unaryOp/longOverflow.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/box/unit") public static class Unit extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInUnit() throws Exception { @@ -4964,6 +5040,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { TestSuite suite = new TestSuite("BlackBoxCodegenTestGenerated"); suite.addTestSuite(BlackBoxCodegenTestGenerated.class); suite.addTestSuite(Arrays.class); + suite.addTestSuite(BinaryOp.class); suite.addTestSuite(Bridges.class); suite.addTestSuite(BuiltinStubMethods.class); suite.addTestSuite(CallableReference.class); @@ -5003,6 +5080,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { suite.addTestSuite(Traits.class); suite.addTestSuite(TypeInfo.class); suite.addTestSuite(TypeMapping.class); + suite.addTestSuite(UnaryOp.class); suite.addTestSuite(Unit.class); suite.addTestSuite(Vararg.class); suite.addTestSuite(When.class);