diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index c9b113c955a..871377e6386 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3634,18 +3634,32 @@ public class ExpressionCodegen extends KtVisitor impleme /*tries to use IEEE 754 arithmetic*/ private StackValue genEqualsForExpressionsPreferIEEE754Arithmetic( - @Nullable KtExpression left, - @Nullable KtExpression right, - @NotNull IElementType opToken, + @Nullable final KtExpression left, + @Nullable final KtExpression right, + @NotNull final IElementType opToken, @NotNull Type leftType, @NotNull Type rightType, - @Nullable StackValue pregeneratedLeft + @Nullable final StackValue pregeneratedLeft ) { - Type left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left); - Type right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right); - if (left754Type != null && right754Type != null && left754Type.equals(right754Type)) { - leftType = left754Type; - rightType = right754Type; + assert (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) : "Optoken should be '==' or '!=', but: " + opToken; + + final TypeAndNullability left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left); + final TypeAndNullability right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right); + if (left754Type != null && right754Type != null && left754Type.type.equals(right754Type.type)) { + 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; + } + }); + } + else { + leftType = left754Type.type; + rightType = right754Type.type; + } } return genEqualsForExpressionsOnStack( @@ -3655,6 +3669,99 @@ public class ExpressionCodegen extends KtVisitor impleme ); } + private void generate754EqualsForNullableTypes( + InstructionAdapter v, + @NotNull IElementType opToken, + @Nullable StackValue pregeneratedLeft, + @Nullable KtExpression left, + TypeAndNullability left754Type, + @Nullable KtExpression right, + TypeAndNullability right754Type + ) { + int equals = opToken == KtTokens.EQEQ ? 1 : 0; + int notEquals = opToken != KtTokens.EQEQ ? 1 : 0; + Label end = new Label(); + StackValue leftValue = pregeneratedLeft != null ? pregeneratedLeft : gen(left); + leftValue.put(leftValue.type, v); + leftValue = StackValue.onStack(leftValue.type); + Type leftType = left754Type.type; + Type rightType = right754Type.type; + if (left754Type.isNullable) { + leftValue.dup(v, false); + Label leftIsNull = new Label(); + v.ifnull(leftIsNull); + StackValue.coercion(leftValue, leftType).put(leftType, v); + StackValue nonNullLeftValue = StackValue.onStack(leftType); + + StackValue rightValue = gen(right); + rightValue.put(rightValue.type, v); + rightValue = StackValue.onStack(rightValue.type); + if (right754Type.isNullable) { + rightValue.dup(v, false); + Label rightIsNotNull = new Label(); + v.ifnonnull(rightIsNotNull); + AsmUtil.pop(v, rightValue.type); + AsmUtil.pop(v, nonNullLeftValue.type); + v.aconst(notEquals); + v.goTo(end); + v.mark(rightIsNotNull); + } + + StackValue.coercion(rightValue, rightType).put(rightType, v); + StackValue nonNullRightValue = StackValue.onStack(rightType); + StackValue.cmp(opToken, leftType, nonNullLeftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, v); + v.goTo(end); + + //left is null case + v.mark(leftIsNull); + AsmUtil.pop(v, leftValue.type);//pop null left + rightValue = gen(right); + rightValue.put(rightValue.type, v); + rightValue = StackValue.onStack(rightValue.type); + if (right754Type.isNullable) { + Label rightIsNotNull = new Label(); + v.ifnonnull(rightIsNotNull); + v.aconst(equals); + v.goTo(end); + v.mark(rightIsNotNull); + v.aconst(notEquals); + //v.goTo(end); + } + else { + AsmUtil.pop(v, rightValue.type); + v.aconst(notEquals); + //v.goTo(end); + } + + v.mark(end); + return; + } + else { + StackValue.coercion(leftValue, leftType).put(leftType, v); + leftValue = StackValue.onStack(leftType); + } + + //right is nullable cause left is not + StackValue rightValue = gen(right); + rightValue.put(rightValue.type, v); + rightValue = StackValue.onStack(rightValue.type); + + rightValue.dup(v, false); + Label rightIsNotNull = new Label(); + v.ifnonnull(rightIsNotNull); + AsmUtil.pop(v, rightValue.type); + AsmUtil.pop(v, leftValue.type); + v.aconst(notEquals); + v.goTo(end); + + v.mark(rightIsNotNull); + StackValue.coercion(rightValue, rightType).put(rightType, v); + StackValue nonNullRightValue = StackValue.onStack(rightType); + StackValue.cmp(opToken, leftType, leftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, v); + + v.mark(end); + } + private boolean isIntZero(KtExpression expr, Type exprType) { ConstantValue exprValue = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals()); return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue()); @@ -3716,12 +3823,12 @@ public class ExpressionCodegen extends KtVisitor impleme StackValue rightValue; Type leftType = expressionType(left); Type rightType = expressionType(right); - Type left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left); - Type right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right); + TypeAndNullability left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left); + TypeAndNullability right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right); Callable callable = resolveToCallable((FunctionDescriptor) resolvedCall.getResultingDescriptor(), false, resolvedCall); - boolean is754Arithmetic = left754Type != null && right754Type != null && left754Type.equals(right754Type); + boolean is754Arithmetic = left754Type != null && right754Type != null && left754Type.type.equals(right754Type.type); if (callable instanceof IntrinsicCallable && ((isPrimitive(leftType) && isPrimitive(rightType)) || is754Arithmetic)) { - type = is754Arithmetic ? left754Type : comparisonOperandType(leftType, rightType); + type = is754Arithmetic ? left754Type.type : comparisonOperandType(leftType, rightType); leftValue = gen(left); rightValue = gen(right); } @@ -3733,7 +3840,7 @@ public class ExpressionCodegen extends KtVisitor impleme return StackValue.cmp(expression.getOperationToken(), type, leftValue, rightValue); } - private Type calcTypeForIEEE754ArithmeticIfNeeded(@Nullable KtExpression expression) { + private TypeAndNullability calcTypeForIEEE754ArithmeticIfNeeded(@Nullable KtExpression expression) { return CodegenUtilKt.calcTypeForIEEE754ArithmeticIfNeeded(expression, bindingContext, context.getFunctionDescriptor()); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt index 78e0d5e7ad3..f4f4271d88b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.types.isFlexible import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.org.objectweb.asm.Label @@ -270,25 +271,27 @@ private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor) fun Collection.filterOutDescriptorsWithSpecialNames() = filterNot { it.name.isSpecial } -fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingContext: BindingContext, descriptor: DeclarationDescriptor): Type? { +class TypeAndNullability(@JvmField val type: Type, @JvmField val isNullable: Boolean) + +fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingContext: BindingContext, descriptor: DeclarationDescriptor): TypeAndNullability? { val ktType = expression.kotlinType(bindingContext) ?: return null if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) { - return Type.DOUBLE_TYPE + return TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(ktType)) } if (KotlinBuiltIns.isFloatOrNullableFloat(ktType)) { - return Type.FLOAT_TYPE + return TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(ktType)) } val dataFlow = DataFlowValueFactory.createDataFlowValue(expression!!, ktType, bindingContext, descriptor) val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow) return stableTypes.firstNotNullResult { if (KotlinBuiltIns.isDoubleOrNullableDouble(it)) { - Type.DOUBLE_TYPE + TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(ktType)) } else if (KotlinBuiltIns.isFloatOrNullableFloat(it)) { - Type.FLOAT_TYPE + TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(ktType)) } else { null diff --git a/compiler/testData/codegen/box/ieee754/equalsNullableDouble.kt b/compiler/testData/codegen/box/ieee754/equalsNullableDouble.kt index 229629cb1e5..f6e04610024 100644 --- a/compiler/testData/codegen/box/ieee754/equalsNullableDouble.kt +++ b/compiler/testData/codegen/box/ieee754/equalsNullableDouble.kt @@ -23,7 +23,11 @@ fun box(): String { if (!equals5(-0.0, 0.0)) return "fail 5" if (!equals6(-0.0, 0.0)) return "fail 6" if (!equals7(-0.0, 0.0)) return "fail 7" + 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" } diff --git a/compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt b/compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt new file mode 100644 index 00000000000..3ab6193b186 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt @@ -0,0 +1,34 @@ +fun equals1(a: Float, b: Float?) = a == b + +fun equals2(a: Float?, b: Float?) = a!! == b!! + +fun equals3(a: Float?, b: Float?) = a != null && a == b + +fun equals4(a: Float?, b: Float?) = if (a is Float) a == b else null!! + +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 equals7(a: Float?, b: Float?) = a == b + +fun equals8(a: Any?, b: Any?) = if (a is Float? && b is Float?) a == b else null!! + + +fun box(): String { + if (!equals1(-0.0F, 0.0F)) return "fail 1" + if (!equals2(-0.0F, 0.0F)) return "fail 2" + if (!equals3(-0.0F, 0.0F)) return "fail 3" + if (!equals4(-0.0F, 0.0F)) return "fail 4" + if (!equals5(-0.0F, 0.0F)) return "fail 5" + if (!equals6(-0.0F, 0.0F)) return "fail 6" + if (!equals7(-0.0F, 0.0F)) return "fail 7" + + 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" +} + diff --git a/compiler/testData/codegen/box/ieee754/nullableDoubleEquals.kt b/compiler/testData/codegen/box/ieee754/nullableDoubleEquals.kt new file mode 100644 index 00000000000..b9423f1135c --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableDoubleEquals.kt @@ -0,0 +1,25 @@ +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/nullableDoubleNotEquals.kt b/compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals.kt new file mode 100644 index 00000000000..c10a2097d37 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableDoubleNotEquals.kt @@ -0,0 +1,25 @@ +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/nullableFloatEquals.kt b/compiler/testData/codegen/box/ieee754/nullableFloatEquals.kt new file mode 100644 index 00000000000..1b18e826ea7 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableFloatEquals.kt @@ -0,0 +1,25 @@ +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/nullableFloatNotEquals.kt b/compiler/testData/codegen/box/ieee754/nullableFloatNotEquals.kt new file mode 100644 index 00000000000..2add42c33d8 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableFloatNotEquals.kt @@ -0,0 +1,25 @@ +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/nullableIntEquals.kt b/compiler/testData/codegen/box/ieee754/nullableIntEquals.kt new file mode 100644 index 00000000000..d0426edb842 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/nullableIntEquals.kt @@ -0,0 +1,26 @@ +//NB: special ieee754 arithmetic logic is not applied to Int comparison +fun myEquals(a: Int?, b: Int?) = a == b + +fun myEquals1(a: Int?, b: Int) = a == b + +fun myEquals2(a: Int, b: Int?) = a == b + +fun myEquals0(a: Int, b: Int) = a == b + + +fun box(): String { + if (!myEquals(null, null)) return "fail 1" + if (myEquals(null, 0)) return "fail 2" + if (myEquals(0, null)) return "fail 3" + if (!myEquals(0, 0)) return "fail 4" + + if (myEquals1(null, 0)) return "fail 5" + if (!myEquals1(0, 0)) return "fail 6" + + if (myEquals2(0, null)) return "fail 7" + if (!myEquals2(0, 0)) return "fail 8" + + if (!myEquals0(0, 0)) return "fail 9" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxAgainstJava/ieee754/double.kt b/compiler/testData/codegen/boxAgainstJava/ieee754/double.kt index ffb123d332e..4c87b414db2 100644 --- a/compiler/testData/codegen/boxAgainstJava/ieee754/double.kt +++ b/compiler/testData/codegen/boxAgainstJava/ieee754/double.kt @@ -35,8 +35,14 @@ fun box(): String { if (jClass.minus0() != jClass.plus0()) return "fail 5" - //TODO: KT-14989 - //if (jClass.null0() != jClass.plus0()) return "fail 6" + var value = jClass.minus0() == jClass.plus0() + if (!value) return "fail 6" + + if (jClass.null0() == jClass.plus0()) return "fail 7" + if (jClass.plus0() == jClass.null0()) return "fail 8" + + value = jClass.null0() == jClass.null0() + if (!value) return "fail 9" return "OK" } diff --git a/compiler/testData/codegen/boxAgainstJava/ieee754/float.kt b/compiler/testData/codegen/boxAgainstJava/ieee754/float.kt index 2d0478c060b..79ba6398e35 100644 --- a/compiler/testData/codegen/boxAgainstJava/ieee754/float.kt +++ b/compiler/testData/codegen/boxAgainstJava/ieee754/float.kt @@ -38,8 +38,14 @@ fun box(): String { if (jClass.minus0() != jClass.plus0()) return "fail 5" - //TODO: KT-14989 - //if (jClass.null0() != jClass.plus0()) return "fail 6" + var value = jClass.minus0() == jClass.plus0() + if (!value) return "fail 6" + + if (jClass.null0() == jClass.plus0()) return "fail 7" + if (jClass.plus0() == jClass.null0()) return "fail 8" + + value = jClass.null0() == jClass.null0() + if (!value) return "fail 9" return "OK" } diff --git a/compiler/testData/codegen/light-analysis/ieee754/equalsNullableFloat.txt b/compiler/testData/codegen/light-analysis/ieee754/equalsNullableFloat.txt new file mode 100644 index 00000000000..a17cc444aff --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/equalsNullableFloat.txt @@ -0,0 +1,12 @@ +@kotlin.Metadata +public final class EqualsNullableFloatKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method equals1(p0: float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method equals2(@org.jetbrains.annotations.Nullable p0: java.lang.Float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method equals3(@org.jetbrains.annotations.Nullable p0: java.lang.Float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method equals4(@org.jetbrains.annotations.Nullable p0: java.lang.Float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method equals5(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals6(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals7(@org.jetbrains.annotations.Nullable p0: java.lang.Float, @org.jetbrains.annotations.Nullable p1: java.lang.Float): boolean + public final static method equals8(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean +} diff --git a/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleEquals.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleEquals.txt new file mode 100644 index 00000000000..5c61cb044c0 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleEquals.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableDoubleEqualsKt { + 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/nullableDoubleNotEquals.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleNotEquals.txt new file mode 100644 index 00000000000..708f482a068 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableDoubleNotEquals.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableDoubleNotEqualsKt { + 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/nullableFloatEquals.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatEquals.txt new file mode 100644 index 00000000000..cce1a0ac506 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatEquals.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableFloatEqualsKt { + 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/nullableFloatNotEquals.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatNotEquals.txt new file mode 100644 index 00000000000..f280abc2ce2 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableFloatNotEquals.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableFloatNotEqualsKt { + 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/nullableIntEquals.txt b/compiler/testData/codegen/light-analysis/ieee754/nullableIntEquals.txt new file mode 100644 index 00000000000..0df80aacef5 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/ieee754/nullableIntEquals.txt @@ -0,0 +1,8 @@ +@kotlin.Metadata +public final class NullableIntEqualsKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method myEquals(@org.jetbrains.annotations.Nullable p0: java.lang.Integer, @org.jetbrains.annotations.Nullable p1: java.lang.Integer): boolean + public final static method myEquals0(p0: int, p1: int): boolean + public final static method myEquals1(@org.jetbrains.annotations.Nullable p0: java.lang.Integer, p1: int): boolean + public final static method myEquals2(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Integer): boolean +} 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 1d2c04e1118..c34b23342d4 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 @@ -8339,6 +8339,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("equalsNullableFloat.kt") + public void testEqualsNullableFloat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt"); + doTest(fileName); + } + @TestMetadata("explicitCompareCall.kt") public void testExplicitCompareCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/explicitCompareCall.kt"); @@ -8393,6 +8399,36 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("nullableDoubleEquals.kt") + public void testNullableDoubleEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals.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("nullableFloatEquals.kt") + public void testNullableFloatEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.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("nullableIntEquals.kt") + public void testNullableIntEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); + doTest(fileName); + } + @TestMetadata("safeCall.kt") public void testSafeCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/safeCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8d530c9c01f..63fdae54dc4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -8339,6 +8339,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("equalsNullableFloat.kt") + public void testEqualsNullableFloat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt"); + doTest(fileName); + } + @TestMetadata("explicitCompareCall.kt") public void testExplicitCompareCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/explicitCompareCall.kt"); @@ -8393,6 +8399,36 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("nullableDoubleEquals.kt") + public void testNullableDoubleEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals.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("nullableFloatEquals.kt") + public void testNullableFloatEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.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("nullableIntEquals.kt") + public void testNullableIntEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); + doTest(fileName); + } + @TestMetadata("safeCall.kt") public void testSafeCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/safeCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java index bd134e52a9f..0521fc8b1c1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java @@ -8339,6 +8339,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("equalsNullableFloat.kt") + public void testEqualsNullableFloat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt"); + doTest(fileName); + } + @TestMetadata("explicitCompareCall.kt") public void testExplicitCompareCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/explicitCompareCall.kt"); @@ -8393,6 +8399,36 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("nullableDoubleEquals.kt") + public void testNullableDoubleEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals.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("nullableFloatEquals.kt") + public void testNullableFloatEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.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("nullableIntEquals.kt") + public void testNullableIntEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); + doTest(fileName); + } + @TestMetadata("safeCall.kt") public void testSafeCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/safeCall.kt"); 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 075b4cccfef..67a9f8fe5ae 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 @@ -9384,6 +9384,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("equalsNullableFloat.kt") + public void testEqualsNullableFloat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/equalsNullableFloat.kt"); + doTest(fileName); + } + @TestMetadata("explicitCompareCall.kt") public void testExplicitCompareCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/explicitCompareCall.kt"); @@ -9456,6 +9462,36 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("nullableDoubleEquals.kt") + public void testNullableDoubleEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableDoubleEquals.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("nullableFloatEquals.kt") + public void testNullableFloatEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableFloatEquals.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("nullableIntEquals.kt") + public void testNullableIntEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/nullableIntEquals.kt"); + doTest(fileName); + } + @TestMetadata("safeCall.kt") public void testSafeCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ieee754/safeCall.kt");