diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 2244066b24b..b6f00c0de41 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -587,6 +587,10 @@ public class AsmUtil { v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false); } + public static void genIEEE754EqualForNullableTypesCall(InstructionAdapter v, Type left, Type right) { + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(" + left.getDescriptor() + right.getDescriptor() + ")Z", false); + } + public static void numConst(int value, Type type, InstructionAdapter v) { if (type == Type.FLOAT_TYPE) { v.fconst(value); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 22535928ec5..770359c596d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -50,6 +50,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.when.SwitchCodegen; import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil; +import org.jetbrains.kotlin.config.ApiVersion; +import org.jetbrains.kotlin.config.LanguageVersion; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor; @@ -143,6 +145,8 @@ public class ExpressionCodegen extends KtVisitor impleme private boolean shouldMarkLineNumbers = true; private int finallyDepth = 0; + private static final ApiVersion apiVersion1_1 = ApiVersion.createByLanguageVersion(LanguageVersion.KOTLIN_1_1); + public ExpressionCodegen( @NotNull MethodVisitor mv, @NotNull FrameMap frameMap, @@ -3646,15 +3650,27 @@ public class ExpressionCodegen extends KtVisitor impleme final TypeAndNullability left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left); final TypeAndNullability right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right); if (left754Type != null && right754Type != null && left754Type.type.equals(right754Type.type)) { + //check nullability cause there is some optimizations in codegen for non-nullable case if (left754Type.isNullable || right754Type.isNullable) { - //check nullability cause there is some optimizations in codegen for non-nullable case - return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { - @Override - public Unit invoke(InstructionAdapter v) { - generate754EqualsForNullableTypes(v, opToken, pregeneratedLeft, left, left754Type, right, right754Type); - return Unit.INSTANCE; - } - }); + if (state.getLanguageVersionSettings().getLanguageVersion() != LanguageVersion.KOTLIN_1_0 && + state.getLanguageVersionSettings().getApiVersion().compareTo(apiVersion1_1) >= 0) { + return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { + @Override + public Unit invoke(InstructionAdapter v) { + generate754EqualsForNullableTypesViaIntrinsic(v, opToken, pregeneratedLeft, left, left754Type, right, right754Type); + return Unit.INSTANCE; + } + }); + } + else { + return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { + @Override + public Unit invoke(InstructionAdapter v) { + generate754EqualsForNullableTypes(v, opToken, pregeneratedLeft, left, left754Type, right, right754Type); + return Unit.INSTANCE; + } + }); + } } else { leftType = left754Type.type; @@ -3669,6 +3685,33 @@ public class ExpressionCodegen extends KtVisitor impleme ); } + private void generate754EqualsForNullableTypesViaIntrinsic( + @NotNull InstructionAdapter v, + @NotNull IElementType opToken, + @Nullable StackValue pregeneratedLeft, + @Nullable KtExpression left, + @NotNull TypeAndNullability left754Type, + @Nullable KtExpression right, + @NotNull TypeAndNullability right754Type + ) { + Type leftType = left754Type.isNullable ? AsmUtil.boxType(left754Type.type) : left754Type.type; + + if (pregeneratedLeft != null) { + StackValue.coercion(pregeneratedLeft, leftType).put(leftType, v); + } + else { + gen(left, leftType); + } + Type rightType = right754Type.isNullable ? AsmUtil.boxType(right754Type.type) : right754Type.type; + gen(right, rightType); + + AsmUtil.genIEEE754EqualForNullableTypesCall(v, leftType, rightType); + + if (opToken == KtTokens.EXCLEQ) { + genInvertBoolean(v); + } + } + private void generate754EqualsForNullableTypes( @NotNull InstructionAdapter v, @NotNull IElementType opToken, diff --git a/compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt b/compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt new file mode 100644 index 00000000000..aec2421eaa9 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt @@ -0,0 +1,26 @@ +// LANGUAGE_VERSION: 1.0 +fun myEquals(a: Double?, b: Double?) = a == b + +fun myEquals1(a: Double?, b: Double) = a == b + +fun myEquals2(a: Double, b: Double?) = a == b + +fun myEquals0(a: Double, b: Double) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0.0)) return "fail 2" + if (myEquals(0.0, null)) return "fail 3" + if (!myEquals(0.0, 0.0)) return "fail 4" + + if (myEquals1(null, 0.0)) return "fail 5" + if (!myEquals1(0.0, 0.0)) return "fail 6" + + if (myEquals2(0.0, null)) return "fail 7" + if (!myEquals2(0.0, 0.0)) return "fail 8" + + if (!myEquals0(0.0, 0.0)) return "fail 9" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt b/compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt new file mode 100644 index 00000000000..7ec29384f5a --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt @@ -0,0 +1,26 @@ +// LANGUAGE_VERSION: 1.0 +fun myNotEquals(a: Double?, b: Double?) = a != b + +fun myNotEquals1(a: Double?, b: Double) = a != b + +fun myNotEquals2(a: Double, b: Double?) = a != b + +fun myNotEquals0(a: Double, b: Double) = a != b + + +fun box(): String { + if (myNotEquals(null, null)) return "fail 1" + if (!myNotEquals(null, 0.0)) return "fail 2" + if (!myNotEquals(0.0, null)) return "fail 3" + if (myNotEquals(0.0, 0.0)) return "fail 4" + + if (!myNotEquals1(null, 0.0)) return "fail 5" + if (myNotEquals1(0.0, 0.0)) return "fail 6" + + if (!myNotEquals2(0.0, null)) return "fail 7" + if (myNotEquals2(0.0, 0.0)) return "fail 8" + + if (myNotEquals0(0.0, 0.0)) return "fail 9" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt b/compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt new file mode 100644 index 00000000000..b6899058120 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt @@ -0,0 +1,26 @@ +// LANGUAGE_VERSION: 1.0 +fun myEquals(a: Float?, b: Float?) = a == b + +fun myEquals1(a: Float?, b: Float) = a == b + +fun myEquals2(a: Float, b: Float?) = a == b + +fun myEquals0(a: Float, b: Float) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0.0F)) return "fail 2" + if (myEquals(0.0F, null)) return "fail 3" + if (!myEquals(0.0F, 0.0F)) return "fail 4" + + if (myEquals1(null, 0.0F)) return "fail 5" + if (!myEquals1(0.0F, 0.0F)) return "fail 6" + + if (myEquals2(0.0F, null)) return "fail 7" + if (!myEquals2(0.0F, 0.0F)) return "fail 8" + + if (!myEquals0(0.0F, 0.0F)) return "fail 9" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt b/compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt new file mode 100644 index 00000000000..a9eeb821db4 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt @@ -0,0 +1,26 @@ +// LANGUAGE_VERSION: 1.0 +fun myNotEquals(a: Float?, b: Float?) = a != b + +fun myNotEquals1(a: Float?, b: Float) = a != b + +fun myNotEquals2(a: Float, b: Float?) = a != b + +fun myNotEquals0(a: Float, b: Float) = a != b + + +fun box(): String { + if (myNotEquals(null, null)) return "fail 1" + if (!myNotEquals(null, 0.0F)) return "fail 2" + if (!myNotEquals(0.0F, null)) return "fail 3" + if (myNotEquals(0.0F, 0.0F)) return "fail 4" + + if (!myNotEquals1(null, 0.0F)) return "fail 5" + if (myNotEquals1(0.0F, 0.0F)) return "fail 6" + + if (!myNotEquals2(0.0F, null)) return "fail 7" + if (myNotEquals2(0.0F, 0.0F)) return "fail 8" + + if (myNotEquals0(0.0F, 0.0F)) return "fail 9" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ieee754/when.kt b/compiler/testData/codegen/box/ieee754/when.kt index c57947e17bf..de5b07e4889 100644 --- a/compiler/testData/codegen/box/ieee754/when.kt +++ b/compiler/testData/codegen/box/ieee754/when.kt @@ -1,18 +1,25 @@ fun box(): String { val plusZero: Any = 0.0 val minusZero: Any = -0.0 + val nullDouble: Double? = null if (plusZero is Double) { when (plusZero) { + nullDouble -> { + return "fail 1" + } -0.0 -> { } - else -> return "fail 1" + else -> return "fail 2" } if (minusZero is Double) { when (plusZero) { + nullDouble -> { + return "fail 3" + } minusZero -> { } - else -> return "fail 2" + else -> return "fail 4" } } } diff --git a/compiler/testData/codegen/box/ieee754/when10.kt b/compiler/testData/codegen/box/ieee754/when10.kt new file mode 100644 index 00000000000..cf42bdd6ac8 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/when10.kt @@ -0,0 +1,29 @@ +// LANGUAGE_VERSION: 1.0 +fun box(): String { + val plusZero: Any = 0.0 + val minusZero: Any = -0.0 + val nullDouble: Double? = null + if (plusZero is Double) { + when (plusZero) { + nullDouble -> { + return "fail 1" + } + -0.0 -> { + } + else -> return "fail 2" + } + + if (minusZero is Double) { + when (plusZero) { + nullDouble -> { + return "fail 3" + } + minusZero -> { + } + else -> return "fail 4" + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt b/compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt new file mode 100644 index 00000000000..31dcd7c4417 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt @@ -0,0 +1,27 @@ +fun box(): String { + val nullValue: Any? = null + val nullDouble: Double? = null + val minusZero: Any = -0.0 + if (nullValue is Double?) { + when (nullValue) { + -0.0 -> { + return "fail 1" + } + nullDouble -> {} + else -> return "fail 2" + } + + if (minusZero is Double) { + when (nullValue) { + minusZero -> { + return "fail 3" + } + nullDouble -> { + } + else -> return "fail 4" + } + } + + } + return "OK" +} diff --git a/compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt b/compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt new file mode 100644 index 00000000000..f497a7468b6 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt @@ -0,0 +1,28 @@ +// LANGUAGE_VERSION: 1.0 +fun box(): String { + val nullValue: Any? = null + val nullDouble: Double? = null + val minusZero: Any = -0.0 + if (nullValue is Double?) { + when (nullValue) { + -0.0 -> { + return "fail 1" + } + nullDouble -> {} + else -> return "fail 2" + } + + if (minusZero is Double) { + when (nullValue) { + minusZero -> { + return "fail 3" + } + nullDouble -> { + } + else -> return "fail 4" + } + } + + } + return "OK" +} diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals.kt new file mode 100644 index 00000000000..47c2df450e0 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals.kt @@ -0,0 +1,30 @@ +fun myEquals(a: Double?, b: Double?) = a == b + +fun myEquals1(a: Double?, b: Double) = a == b + +fun myEquals2(a: Double, b: Double?) = a == b + +fun myEquals0(a: Double, b: Double) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0.0)) return "fail 2" + if (myEquals(0.0, null)) return "fail 3" + if (!myEquals(0.0, 0.0)) return "fail 4" + + if (myEquals1(null, 0.0)) return "fail 5" + if (!myEquals1(0.0, 0.0)) return "fail 6" + + if (myEquals2(0.0, null)) return "fail 7" + if (!myEquals2(0.0, 0.0)) return "fail 8" + + if (!myEquals0(0.0, 0.0)) return "fail 9" + + return "OK" +} + +// 1 areEqual \(Ljava/lang/Double;Ljava/lang/Double;\)Z +// 1 areEqual \(DLjava/lang/Double;\)Z +// 1 areEqual \(Ljava/lang/Double;D\)Z +// 3 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals10.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals10.kt new file mode 100644 index 00000000000..029a5579080 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals10.kt @@ -0,0 +1,29 @@ +// LANGUAGE_VERSION: 1.0 + +fun myEquals(a: Double?, b: Double?) = a == b + +fun myEquals1(a: Double?, b: Double) = a == b + +fun myEquals2(a: Double, b: Double?) = a == b + +fun myEquals0(a: Double, b: Double) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0.0)) return "fail 2" + if (myEquals(0.0, null)) return "fail 3" + if (!myEquals(0.0, 0.0)) return "fail 4" + + if (myEquals1(null, 0.0)) return "fail 5" + if (!myEquals1(0.0, 0.0)) return "fail 6" + + if (myEquals2(0.0, null)) return "fail 7" + if (!myEquals2(0.0, 0.0)) return "fail 8" + + if (!myEquals0(0.0, 0.0)) return "fail 9" + + return "OK" +} + +// 0 areEquals \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals.kt new file mode 100644 index 00000000000..f5738395a6c --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals.kt @@ -0,0 +1,30 @@ +fun myNotEquals(a: Double?, b: Double?) = a != b + +fun myNotEquals1(a: Double?, b: Double) = a != b + +fun myNotEquals2(a: Double, b: Double?) = a != b + +fun myNotEquals0(a: Double, b: Double) = a != b + + +fun box(): String { + if (myNotEquals(null, null)) return "fail 1" + if (!myNotEquals(null, 0.0)) return "fail 2" + if (!myNotEquals(0.0, null)) return "fail 3" + if (myNotEquals(0.0, 0.0)) return "fail 4" + + if (!myNotEquals1(null, 0.0)) return "fail 5" + if (myNotEquals1(0.0, 0.0)) return "fail 6" + + if (!myNotEquals2(0.0, null)) return "fail 7" + if (myNotEquals2(0.0, 0.0)) return "fail 8" + + if (myNotEquals0(0.0, 0.0)) return "fail 9" + + return "OK" +} + +// 1 areEqual \(Ljava/lang/Double;Ljava/lang/Double;\)Z +// 1 areEqual \(DLjava/lang/Double;\)Z +// 1 areEqual \(Ljava/lang/Double;D\)Z +// 3 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals10.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals10.kt new file mode 100644 index 00000000000..b97c8fcbee4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals10.kt @@ -0,0 +1,28 @@ +// LANGUAGE_VERSION: 1.0 +fun myNotEquals(a: Double?, b: Double?) = a != b + +fun myNotEquals1(a: Double?, b: Double) = a != b + +fun myNotEquals2(a: Double, b: Double?) = a != b + +fun myNotEquals0(a: Double, b: Double) = a != b + + +fun box(): String { + if (myNotEquals(null, null)) return "fail 1" + if (!myNotEquals(null, 0.0)) return "fail 2" + if (!myNotEquals(0.0, null)) return "fail 3" + if (myNotEquals(0.0, 0.0)) return "fail 4" + + if (!myNotEquals1(null, 0.0)) return "fail 5" + if (myNotEquals1(0.0, 0.0)) return "fail 6" + + if (!myNotEquals2(0.0, null)) return "fail 7" + if (myNotEquals2(0.0, 0.0)) return "fail 8" + + if (myNotEquals0(0.0, 0.0)) return "fail 9" + + return "OK" +} + +// 0 areEquals \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals.kt new file mode 100644 index 00000000000..77a8be7b67e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals.kt @@ -0,0 +1,30 @@ +fun myEquals(a: Float?, b: Float?) = a == b + +fun myEquals1(a: Float?, b: Float) = a == b + +fun myEquals2(a: Float, b: Float?) = a == b + +fun myEquals0(a: Float, b: Float) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0.0F)) return "fail 2" + if (myEquals(0.0F, null)) return "fail 3" + if (!myEquals(0.0F, 0.0F)) return "fail 4" + + if (myEquals1(null, 0.0F)) return "fail 5" + if (!myEquals1(0.0F, 0.0F)) return "fail 6" + + if (myEquals2(0.0F, null)) return "fail 7" + if (!myEquals2(0.0F, 0.0F)) return "fail 8" + + if (!myEquals0(0.0F, 0.0F)) return "fail 9" + + return "OK" +} + +// 1 areEqual \(Ljava/lang/Float;Ljava/lang/Float;\)Z +// 1 areEqual \(FLjava/lang/Float;\)Z +// 1 areEqual \(Ljava/lang/Float;F\)Z +// 3 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals10.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals10.kt new file mode 100644 index 00000000000..aba2864539a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals10.kt @@ -0,0 +1,28 @@ +// LANGUAGE_VERSION: 1.0 +fun myEquals(a: Float?, b: Float?) = a == b + +fun myEquals1(a: Float?, b: Float) = a == b + +fun myEquals2(a: Float, b: Float?) = a == b + +fun myEquals0(a: Float, b: Float) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0.0F)) return "fail 2" + if (myEquals(0.0F, null)) return "fail 3" + if (!myEquals(0.0F, 0.0F)) return "fail 4" + + if (myEquals1(null, 0.0F)) return "fail 5" + if (!myEquals1(0.0F, 0.0F)) return "fail 6" + + if (myEquals2(0.0F, null)) return "fail 7" + if (!myEquals2(0.0F, 0.0F)) return "fail 8" + + if (!myEquals0(0.0F, 0.0F)) return "fail 9" + + return "OK" +} + +// 0 areEquals \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals.kt new file mode 100644 index 00000000000..ace18422a80 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals.kt @@ -0,0 +1,30 @@ +fun myNotEquals(a: Float?, b: Float?) = a != b + +fun myNotEquals1(a: Float?, b: Float) = a != b + +fun myNotEquals2(a: Float, b: Float?) = a != b + +fun myNotEquals0(a: Float, b: Float) = a != b + + +fun box(): String { + if (myNotEquals(null, null)) return "fail 1" + if (!myNotEquals(null, 0.0F)) return "fail 2" + if (!myNotEquals(0.0F, null)) return "fail 3" + if (myNotEquals(0.0F, 0.0F)) return "fail 4" + + if (!myNotEquals1(null, 0.0F)) return "fail 5" + if (myNotEquals1(0.0F, 0.0F)) return "fail 6" + + if (!myNotEquals2(0.0F, null)) return "fail 7" + if (myNotEquals2(0.0F, 0.0F)) return "fail 8" + + if (myNotEquals0(0.0F, 0.0F)) return "fail 9" + + return "OK" +} + +// 1 areEqual \(Ljava/lang/Float;Ljava/lang/Float;\)Z +// 1 areEqual \(FLjava/lang/Float;\)Z +// 1 areEqual \(Ljava/lang/Float;F\)Z +// 3 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals10.kt b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals10.kt new file mode 100644 index 00000000000..273fdd09a46 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals10.kt @@ -0,0 +1,28 @@ +// LANGUAGE_VERSION: 1.0 +fun myNotEquals(a: Float?, b: Float?) = a != b + +fun myNotEquals1(a: Float?, b: Float) = a != b + +fun myNotEquals2(a: Float, b: Float?) = a != b + +fun myNotEquals0(a: Float, b: Float) = a != b + + +fun box(): String { + if (myNotEquals(null, null)) return "fail 1" + if (!myNotEquals(null, 0.0F)) return "fail 2" + if (!myNotEquals(0.0F, null)) return "fail 3" + if (myNotEquals(0.0F, 0.0F)) return "fail 4" + + if (!myNotEquals1(null, 0.0F)) return "fail 5" + if (myNotEquals1(0.0F, 0.0F)) return "fail 6" + + if (!myNotEquals2(0.0F, null)) return "fail 7" + if (myNotEquals2(0.0F, 0.0F)) return "fail 8" + + if (myNotEquals0(0.0F, 0.0F)) return "fail 9" + + return "OK" +} + +// 0 areEquals \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble.kt b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble.kt new file mode 100644 index 00000000000..3493f052af1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble.kt @@ -0,0 +1,23 @@ +fun equals5(a: Any?, b: Any?) = if (a is Double && b is Double?) a == b else null!! + +fun equals6(a: Any?, b: Any?) = if (a is Double? && b is Double) a == b else null!! + +fun equals8(a: Any?, b: Any?) = if (a is Double? && b is Double?) a == b else null!! + + +fun box(): String { + if (!equals5(-0.0, 0.0)) return "fail 5" + if (!equals6(-0.0, 0.0)) return "fail 6" + + if (!equals8(-0.0, 0.0)) return "fail 8" + if (!equals8(null, null)) return "fail 9" + if (equals8(null, 0.0)) return "fail 10" + if (equals8(0.0, null)) return "fail 11" + + return "OK" +} + +// 1 areEqual \(Ljava/lang/Double;Ljava/lang/Double;\)Z +// 1 areEqual \(DLjava/lang/Double;\)Z +// 1 areEqual \(Ljava/lang/Double;D\)Z +// 3 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble10.kt b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble10.kt new file mode 100644 index 00000000000..ef22c8e335a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble10.kt @@ -0,0 +1,22 @@ +// LANGUAGE_VERSION: 1.0 + +fun equals5(a: Any?, b: Any?) = if (a is Double && b is Double?) a == b else null!! + +fun equals6(a: Any?, b: Any?) = if (a is Double? && b is Double) a == b else null!! + +fun equals8(a: Any?, b: Any?) = if (a is Double? && b is Double?) a == b else null!! + + +fun box(): String { + if (!equals5(-0.0, 0.0)) return "fail 5" + if (!equals6(-0.0, 0.0)) return "fail 6" + + if (!equals8(-0.0, 0.0)) return "fail 8" + if (!equals8(null, null)) return "fail 9" + if (equals8(null, 0.0)) return "fail 10" + if (equals8(0.0, null)) return "fail 11" + + return "OK" +} + +// 0 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat.kt b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat.kt new file mode 100644 index 00000000000..dcf8f65c0c9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat.kt @@ -0,0 +1,23 @@ +fun equals5(a: Any?, b: Any?) = if (a is Float && b is Float?) a == b else null!! + +fun equals6(a: Any?, b: Any?) = if (a is Float? && b is Float) a == b else null!! + +fun equals8(a: Any?, b: Any?) = if (a is Float? && b is Float?) a == b else null!! + + +fun box(): String { + if (!equals5(-0.0F, 0.0F)) return "fail 5" + if (!equals6(-0.0F, 0.0F)) return "fail 6" + + if (!equals8(-0.0F, 0.0F)) return "fail 8" + if (!equals8(null, null)) return "fail 9" + if (equals8(null, 0.0F)) return "fail 10" + if (equals8(0.0F, null)) return "fail 11" + + return "OK" +} + +// 1 areEqual \(Ljava/lang/Float;Ljava/lang/Float;\)Z +// 1 areEqual \(FLjava/lang/Float;\)Z +// 1 areEqual \(Ljava/lang/Float;F\)Z +// 3 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat10.kt b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat10.kt new file mode 100644 index 00000000000..7758e877b83 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat10.kt @@ -0,0 +1,22 @@ +// LANGUAGE_VERSION: 1.0 + +fun equals5(a: Any?, b: Any?) = if (a is Float && b is Float?) a == b else null!! + +fun equals6(a: Any?, b: Any?) = if (a is Float? && b is Float) a == b else null!! + +fun equals8(a: Any?, b: Any?) = if (a is Float? && b is Float?) a == b else null!! + + +fun box(): String { + if (!equals5(-0.0F, 0.0F)) return "fail 5" + if (!equals6(-0.0F, 0.0F)) return "fail 6" + + if (!equals8(-0.0F, 0.0F)) return "fail 8" + if (!equals8(null, null)) return "fail 9" + if (equals8(null, 0.0F)) return "fail 10" + if (equals8(0.0F, null)) return "fail 11" + + return "OK" +} + +// 0 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/when.kt b/compiler/testData/codegen/bytecodeText/ieee754/when.kt new file mode 100644 index 00000000000..44965474b43 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/when.kt @@ -0,0 +1,31 @@ +fun box(): String { + val plusZero: Any = 0.0 + val minusZero: Any = -0.0 + val nullDouble: Double? = null + if (plusZero is Double) { + when (plusZero) { + nullDouble -> { + return "fail 1" + } + -0.0 -> { + } + else -> return "fail 2" + } + + if (minusZero is Double) { + when (plusZero) { + nullDouble -> { + return "fail 3" + } + minusZero -> { + } + else -> return "fail 4" + } + } + } + + return "OK" +} + +// 2 areEqual \(DLjava/lang/Double;\)Z +// 2 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/when10.kt b/compiler/testData/codegen/bytecodeText/ieee754/when10.kt new file mode 100644 index 00000000000..007dd5dd698 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/when10.kt @@ -0,0 +1,31 @@ +// LANGUAGE_VERSION: 1.0 +fun box(): String { + val plusZero: Any = 0.0 + val minusZero: Any = -0.0 + val nullDouble: Double? = null + if (plusZero is Double) { + when (plusZero) { + nullDouble -> { + return "fail 1" + } + -0.0 -> { + } + else -> return "fail 2" + } + + if (minusZero is Double) { + when (plusZero) { + nullDouble -> { + return "fail 3" + } + minusZero -> { + } + else -> return "fail 4" + } + } + } + + return "OK" +} + +// 0 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast.kt b/compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast.kt new file mode 100644 index 00000000000..92573325edf --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast.kt @@ -0,0 +1,31 @@ +fun box(): String { + val nullValue: Any? = null + val nullDouble: Double? = null + val minusZero: Any = -0.0 + if (nullValue is Double?) { + when (nullValue) { + -0.0 -> { + return "fail 1" + } + nullDouble -> {} + else -> return "fail 2" + } + + if (minusZero is Double) { + when (nullValue) { + minusZero -> { + return "fail 3" + } + nullDouble -> { + } + else -> return "fail 4" + } + } + + } + return "OK" +} + +// 2 areEqual \(Ljava/lang/Double;Ljava/lang/Double;\)Z +// 2 areEqual \(Ljava/lang/Double;D\)Z +// 4 areEqual \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast10.kt b/compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast10.kt new file mode 100644 index 00000000000..b1b38fdc643 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast10.kt @@ -0,0 +1,29 @@ +// LANGUAGE_VERSION: 1.0 +fun box(): String { + val nullValue: Any? = null + val nullDouble: Double? = null + val minusZero: Any = -0.0 + if (nullValue is Double?) { + when (nullValue) { + -0.0 -> { + return "fail 1" + } + nullDouble -> {} + else -> return "fail 2" + } + + if (minusZero is Double) { + when (nullValue) { + minusZero -> { + return "fail 3" + } + nullDouble -> { + } + else -> return "fail 4" + } + } + + } + return "OK" +} +// 0 areEqual diff --git a/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleEquals10.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleEquals10.txt new file mode 100644 index 00000000000..653ee7ff123 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleEquals10.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableDoubleEquals10Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method myEquals(@org.jetbrains.annotations.Nullable p0: java.lang.Double, @org.jetbrains.annotations.Nullable p1: java.lang.Double): boolean + public final static method myEquals0(p0: double, p1: double): boolean + public final static method myEquals1(@org.jetbrains.annotations.Nullable p0: java.lang.Double, p1: double): boolean + public final static method myEquals2(p0: double, @org.jetbrains.annotations.Nullable p1: java.lang.Double): boolean +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleNotEquals10.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleNotEquals10.txt new file mode 100644 index 00000000000..78445bae0f9 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleNotEquals10.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableDoubleNotEquals10Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method myNotEquals(@org.jetbrains.annotations.Nullable p0: java.lang.Double, @org.jetbrains.annotations.Nullable p1: java.lang.Double): boolean + public final static method myNotEquals0(p0: double, p1: double): boolean + public final static method myNotEquals1(@org.jetbrains.annotations.Nullable p0: java.lang.Double, p1: double): boolean + public final static method myNotEquals2(p0: double, @org.jetbrains.annotations.Nullable p1: java.lang.Double): boolean +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/nullableFloatEquals10.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatEquals10.txt new file mode 100644 index 00000000000..50ed9df1bbf --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatEquals10.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableFloatEquals10Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method myEquals(@org.jetbrains.annotations.Nullable p0: java.lang.Float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method myEquals0(p0: float, p1: float): boolean + public final static method myEquals1(@org.jetbrains.annotations.Nullable p0: java.lang.Float, p1: float): boolean + public final static method myEquals2(p0: float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/nullableFloatNotEquals10.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatNotEquals10.txt new file mode 100644 index 00000000000..f81801c26c6 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatNotEquals10.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableFloatNotEquals10Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method myNotEquals(@org.jetbrains.annotations.Nullable p0: java.lang.Float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method myNotEquals0(p0: float, p1: float): boolean + public final static method myNotEquals1(@org.jetbrains.annotations.Nullable p0: java.lang.Float, p1: float): boolean + public final static method myNotEquals2(p0: float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/when10.txt b/compiler/testData/codegen/light-analysis/ieee754/when10.txt new file mode 100644 index 00000000000..a9db2237699 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/when10.txt @@ -0,0 +1,4 @@ +@kotlin.Metadata +public final class When10Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/whenNullableSmartCast.txt b/compiler/testData/codegen/light-analysis/ieee754/whenNullableSmartCast.txt new file mode 100644 index 00000000000..acb9523dc6a --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/whenNullableSmartCast.txt @@ -0,0 +1,4 @@ +@kotlin.Metadata +public final class WhenNullableSmartCastKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/whenNullableSmartCast10.txt b/compiler/testData/codegen/light-analysis/ieee754/whenNullableSmartCast10.txt new file mode 100644 index 00000000000..fc7b87f8b8f --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/whenNullableSmartCast10.txt @@ -0,0 +1,4 @@ +@kotlin.Metadata +public final class WhenNullableSmartCast10Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7dc58bd75e6..78b3c3b0c4b 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -8426,24 +8426,48 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("nullableDoubleEquals10.kt") + public void testNullableDoubleEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableDoubleNotEquals.kt") public void testNullableDoubleNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableDoubleNotEquals10.kt") + public void testNullableDoubleNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatEquals.kt") public void testNullableFloatEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatEquals10.kt") + public void testNullableFloatEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatNotEquals.kt") public void testNullableFloatNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatNotEquals10.kt") + public void testNullableFloatNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableIntEquals.kt") public void testNullableIntEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); @@ -8468,11 +8492,29 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("when10.kt") + public void testWhen10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/when10.kt"); + doTest(fileName); + } + @TestMetadata("whenNoSubject.kt") public void testWhenNoSubject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNoSubject.kt"); doTest(fileName); } + + @TestMetadata("whenNullableSmartCast.kt") + public void testWhenNullableSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt"); + doTest(fileName); + } + + @TestMetadata("whenNullableSmartCast10.kt") + public void testWhenNullableSmartCast10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/increment") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 763e8cfa41a..0483e5bf4c7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -8426,24 +8426,48 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("nullableDoubleEquals10.kt") + public void testNullableDoubleEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableDoubleNotEquals.kt") public void testNullableDoubleNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableDoubleNotEquals10.kt") + public void testNullableDoubleNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatEquals.kt") public void testNullableFloatEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatEquals10.kt") + public void testNullableFloatEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatNotEquals.kt") public void testNullableFloatNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatNotEquals10.kt") + public void testNullableFloatNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableIntEquals.kt") public void testNullableIntEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); @@ -8468,11 +8492,29 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("when10.kt") + public void testWhen10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/when10.kt"); + doTest(fileName); + } + @TestMetadata("whenNoSubject.kt") public void testWhenNoSubject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNoSubject.kt"); doTest(fileName); } + + @TestMetadata("whenNullableSmartCast.kt") + public void testWhenNullableSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt"); + doTest(fileName); + } + + @TestMetadata("whenNullableSmartCast10.kt") + public void testWhenNullableSmartCast10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/increment") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 7834edff265..978d4d758b7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1116,6 +1116,111 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { } } + @TestMetadata("compiler/testData/codegen/bytecodeText/ieee754") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Ieee754 extends AbstractBytecodeTextTest { + public void testAllFilesPresentInIeee754() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/ieee754"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("nullableDoubleEquals.kt") + public void testNullableDoubleEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals.kt"); + doTest(fileName); + } + + @TestMetadata("nullableDoubleEquals10.kt") + public void testNullableDoubleEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleEquals10.kt"); + doTest(fileName); + } + + @TestMetadata("nullableDoubleNotEquals.kt") + public void testNullableDoubleNotEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals.kt"); + doTest(fileName); + } + + @TestMetadata("nullableDoubleNotEquals10.kt") + public void testNullableDoubleNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableDoubleNotEquals10.kt"); + doTest(fileName); + } + + @TestMetadata("nullableFloatEquals.kt") + public void testNullableFloatEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals.kt"); + doTest(fileName); + } + + @TestMetadata("nullableFloatEquals10.kt") + public void testNullableFloatEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableFloatEquals10.kt"); + doTest(fileName); + } + + @TestMetadata("nullableFloatNotEquals.kt") + public void testNullableFloatNotEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals.kt"); + doTest(fileName); + } + + @TestMetadata("nullableFloatNotEquals10.kt") + public void testNullableFloatNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/nullableFloatNotEquals10.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastsForDouble.kt") + public void testSmartCastsForDouble() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastsForDouble10.kt") + public void testSmartCastsForDouble10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/smartCastsForDouble10.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastsForFloat.kt") + public void testSmartCastsForFloat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastsForFloat10.kt") + public void testSmartCastsForFloat10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/smartCastsForFloat10.kt"); + doTest(fileName); + } + + @TestMetadata("when.kt") + public void testWhen() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/when.kt"); + doTest(fileName); + } + + @TestMetadata("when10.kt") + public void testWhen10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/when10.kt"); + doTest(fileName); + } + + @TestMetadata("whenNullableSmartCast.kt") + public void testWhenNullableSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast.kt"); + doTest(fileName); + } + + @TestMetadata("whenNullableSmartCast10.kt") + public void testWhenNullableSmartCast10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ieee754/whenNullableSmartCast10.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/bytecodeText/inline") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java index 5b021b21055..f72b1a66f0d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java @@ -8426,24 +8426,48 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("nullableDoubleEquals10.kt") + public void testNullableDoubleEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableDoubleNotEquals.kt") public void testNullableDoubleNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableDoubleNotEquals10.kt") + public void testNullableDoubleNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatEquals.kt") public void testNullableFloatEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatEquals10.kt") + public void testNullableFloatEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatNotEquals.kt") public void testNullableFloatNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatNotEquals10.kt") + public void testNullableFloatNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableIntEquals.kt") public void testNullableIntEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); @@ -8468,11 +8492,29 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("when10.kt") + public void testWhen10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/when10.kt"); + doTest(fileName); + } + @TestMetadata("whenNoSubject.kt") public void testWhenNoSubject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNoSubject.kt"); doTest(fileName); } + + @TestMetadata("whenNullableSmartCast.kt") + public void testWhenNullableSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt"); + doTest(fileName); + } + + @TestMetadata("whenNullableSmartCast10.kt") + public void testWhenNullableSmartCast10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/increment") diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java index b0af8e612a3..27b7257bdbc 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java @@ -163,6 +163,30 @@ public class Intrinsics { return first == null ? second == null : first.equals(second); } + public static boolean areEqual(Double first, Double second) { + return first == null ? second == null : second != null && first.doubleValue() == second.doubleValue(); + } + + public static boolean areEqual(Double first, double second) { + return first != null && first.doubleValue() == second; + } + + public static boolean areEqual(double first, Double second) { + return second != null && first == second.doubleValue(); + } + + public static boolean areEqual(Float first, Float second) { + return first == null ? second == null : second != null && first.floatValue() == second.floatValue(); + } + + public static boolean areEqual(Float first, float second) { + return first != null && first.floatValue() == second; + } + + public static boolean areEqual(float first, Float second) { + return second != null && first == second.floatValue(); + } + public static void throwUndefinedForReified() { throwUndefinedForReified( "This function has a reified type parameter and thus can only be inlined at compilation time, not called directly." diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 3c856630e61..b122ac4402b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -9501,24 +9501,48 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("nullableDoubleEquals10.kt") + public void testNullableDoubleEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableDoubleNotEquals.kt") public void testNullableDoubleNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableDoubleNotEquals10.kt") + public void testNullableDoubleNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatEquals.kt") public void testNullableFloatEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatEquals10.kt") + public void testNullableFloatEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableFloatNotEquals.kt") public void testNullableFloatNotEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals.kt"); doTest(fileName); } + @TestMetadata("nullableFloatNotEquals10.kt") + public void testNullableFloatNotEquals10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatNotEquals10.kt"); + doTest(fileName); + } + @TestMetadata("nullableIntEquals.kt") public void testNullableIntEquals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); @@ -9555,11 +9579,29 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("when10.kt") + public void testWhen10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/when10.kt"); + doTest(fileName); + } + @TestMetadata("whenNoSubject.kt") public void testWhenNoSubject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNoSubject.kt"); doTest(fileName); } + + @TestMetadata("whenNullableSmartCast.kt") + public void testWhenNullableSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast.kt"); + doTest(fileName); + } + + @TestMetadata("whenNullableSmartCast10.kt") + public void testWhenNullableSmartCast10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/whenNullableSmartCast10.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/increment")