diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java
index b262d843388..8a32a2d8de1 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java
@@ -486,29 +486,28 @@ public class AsmUtil {
v.xor(Type.INT_TYPE);
}
+ @NotNull
public static StackValue genEqualsForExpressionsOnStack(
- InstructionAdapter v,
- IElementType opToken,
- Type leftType,
- Type rightType
+ @NotNull InstructionAdapter v,
+ @NotNull IElementType opToken,
+ @NotNull Type leftType,
+ @NotNull Type rightType
) {
- if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) {
+ if (isPrimitive(leftType) && leftType == rightType) {
return StackValue.cmp(opToken, leftType);
}
- else {
- if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) {
- return StackValue.cmp(opToken, leftType);
- }
- else {
- v.invokestatic("kotlin/jvm/internal/Intrinsics", "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
- if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
- genInvertBoolean(v);
- }
-
- return StackValue.onStack(Type.BOOLEAN_TYPE);
- }
+ if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) {
+ return StackValue.cmp(opToken, leftType);
}
+
+ v.invokestatic("kotlin/jvm/internal/Intrinsics", "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
+
+ if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
+ genInvertBoolean(v);
+ }
+
+ return StackValue.onStack(Type.BOOLEAN_TYPE);
}
public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) {
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
index 8f61fe75ba2..0d06b35fb2e 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
@@ -645,15 +645,23 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
else {
iv.invokestatic("java/util/Arrays", "equals",
- "([" + elementType.getDescriptor() + "[" + elementType.getDescriptor() + ")Z", false);
+ "(" + asmType.getDescriptor() + asmType.getDescriptor() + ")Z", false);
}
+ iv.ifeq(ne);
+ }
+ else if (asmType.getSort() == Type.FLOAT) {
+ iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
+ iv.ifne(ne);
+ }
+ else if (asmType.getSort() == Type.DOUBLE) {
+ iv.invokestatic("java/lang/Double", "compare", "(DD)I", false);
+ iv.ifne(ne);
}
else {
StackValue value = genEqualsForExpressionsOnStack(iv, JetTokens.EQEQ, asmType, asmType);
value.put(Type.BOOLEAN_TYPE, iv);
+ iv.ifeq(ne);
}
-
- iv.ifeq(ne);
}
iv.mark(eq);
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
index 1c6ed3673e2..794f997d453 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
@@ -517,7 +517,7 @@ public abstract class StackValue {
opcode = jumpIfFalse ? IFGT : IFLE;
}
else {
- throw new UnsupportedOperationException("don't know how to generate this condjump");
+ throw new UnsupportedOperationException("Don't know how to generate this condJump: " + opToken);
}
if (operandType == Type.FLOAT_TYPE || operandType == Type.DOUBLE_TYPE) {
if (opToken == JetTokens.GT || opToken == JetTokens.GTEQ) {
diff --git a/compiler/testData/codegen/boxWithStdlib/dataClasses/doubleParam.kt b/compiler/testData/codegen/boxWithStdlib/dataClasses/doubleParam.kt
new file mode 100644
index 00000000000..3a97e7002a6
--- /dev/null
+++ b/compiler/testData/codegen/boxWithStdlib/dataClasses/doubleParam.kt
@@ -0,0 +1,30 @@
+import java.util.HashSet
+
+val NAN = java.lang.Double.NaN
+
+data class A(val x: Double)
+
+fun box(): String {
+ if (A(+0.0) == A(-0.0)) return "Fail: +0.0 == -0.0"
+ if (A(+0.0).hashCode() == A(-0.0).hashCode()) return "Fail: hash(+0.0) == hash(-0.0)"
+
+ if (A(NAN) != A(NAN)) return "Fail: NaN != NaN"
+ if (A(NAN).hashCode() != A(NAN).hashCode()) return "Fail: hash(NaN) != hash(NaN)"
+
+ val s = HashSet()
+ for (times in 1..5) {
+ s.add(A(3.14))
+ s.add(A(+0.0))
+ s.add(A(-0.0))
+ s.add(A(-2.72))
+ s.add(A(NAN))
+ }
+
+ if (A(3.14) !in s) return "Fail: 3.14 not found"
+ if (A(+0.0) !in s) return "Fail: +0.0 not found"
+ if (A(-0.0) !in s) return "Fail: -0.0 not found"
+ if (A(-2.72) !in s) return "Fail: -2.72 not found"
+ if (A(NAN) !in s) return "Fail: NaN not found"
+
+ return if (s.size == 5) "OK" else "Fail $s"
+}
diff --git a/compiler/testData/codegen/boxWithStdlib/dataClasses/floatParam.kt b/compiler/testData/codegen/boxWithStdlib/dataClasses/floatParam.kt
new file mode 100644
index 00000000000..5335df49f67
--- /dev/null
+++ b/compiler/testData/codegen/boxWithStdlib/dataClasses/floatParam.kt
@@ -0,0 +1,30 @@
+import java.util.HashSet
+
+val NAN = java.lang.Float.NaN
+
+data class A(val x: Float)
+
+fun box(): String {
+ if (A(+0f) == A(-0f)) return "Fail: +0 == -0"
+ if (A(+0f).hashCode() == A(-0f).hashCode()) return "Fail: hash(+0) == hash(-0)"
+
+ if (A(NAN) != A(NAN)) return "Fail: NaN != NaN"
+ if (A(NAN).hashCode() != A(NAN).hashCode()) return "Fail: hash(NaN) != hash(NaN)"
+
+ val s = HashSet()
+ for (times in 1..5) {
+ s.add(A(3.14f))
+ s.add(A(+0f))
+ s.add(A(-0f))
+ s.add(A(-2.72f))
+ s.add(A(NAN))
+ }
+
+ if (A(3.14f) !in s) return "Fail: 3.14 not found"
+ if (A(+0f) !in s) return "Fail: +0 not found"
+ if (A(-0f) !in s) return "Fail: -0 not found"
+ if (A(-2.72f) !in s) return "Fail: -2.72 not found"
+ if (A(NAN) !in s) return "Fail: NaN not found"
+
+ return if (s.size == 5) "OK" else "Fail $s"
+}
diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java
index 1948b9ea388..f1e40644885 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java
@@ -766,6 +766,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
+ @TestMetadata("doubleParam.kt")
+ public void testDoubleParam() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/dataClasses/doubleParam.kt");
+ doTestWithStdlib(fileName);
+ }
+
+ @TestMetadata("floatParam.kt")
+ public void testFloatParam() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/dataClasses/floatParam.kt");
+ doTestWithStdlib(fileName);
+ }
+
@TestMetadata("genericParam.kt")
public void testGenericParam() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/dataClasses/genericParam.kt");