KT-27948: Properly coerce values when generating areEqual call
#KT-27948
This commit is contained in:
@@ -828,8 +828,8 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
left.put(leftType, v);
|
||||
right.put(rightType, v);
|
||||
left.put(AsmTypes.OBJECT_TYPE, left.kotlinType, v);
|
||||
right.put(AsmTypes.OBJECT_TYPE, right.kotlinType, v);
|
||||
genAreEqualCall(v);
|
||||
|
||||
if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
|
||||
@@ -3548,8 +3548,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
return genEqualsForExpressionsOnStack(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
genLazy(right, rightType)
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType, kotlinType(left)),
|
||||
genLazy(right, rightType, kotlinType(right))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+17
-7
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.FunctionsFromAnyGenerator;
|
||||
@@ -96,7 +97,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
boolean first = true;
|
||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||
if (first) {
|
||||
iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString()+"=");
|
||||
iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
@@ -237,23 +238,32 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
KotlinType kotlinType = propertyDescriptor.getReturnType();
|
||||
Type asmType = typeMapper.mapType(kotlinType);
|
||||
|
||||
JvmKotlinType thisPropertyType = genOrLoadOnStack(iv,context, propertyDescriptor, 0);
|
||||
StackValue.coerce(thisPropertyType.getType(), thisPropertyType.getKotlinType(), asmType, kotlinType, iv);
|
||||
|
||||
JvmKotlinType otherPropertyType = genOrLoadOnStack(iv,context, propertyDescriptor, storedValueIndex);
|
||||
StackValue.coerce(otherPropertyType.getType(), otherPropertyType.getKotlinType(), asmType, kotlinType, iv);
|
||||
StackValue thisPropertyValue = StackValue.operation(asmType, kotlinType, (InstructionAdapter iiv) -> {
|
||||
JvmKotlinType thisPropertyType = genOrLoadOnStack(iiv, context, propertyDescriptor, 0);
|
||||
StackValue.coerce(thisPropertyType.getType(), thisPropertyType.getKotlinType(), asmType, kotlinType, iiv);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
StackValue otherPropertyValue = StackValue.operation(asmType, kotlinType, (InstructionAdapter iiv) -> {
|
||||
JvmKotlinType otherPropertyType = genOrLoadOnStack(iiv, context, propertyDescriptor, storedValueIndex);
|
||||
StackValue.coerce(otherPropertyType.getType(), otherPropertyType.getKotlinType(), asmType, kotlinType, iiv);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
if (asmType.getSort() == Type.FLOAT) {
|
||||
thisPropertyValue.put(asmType, kotlinType, iv);
|
||||
otherPropertyValue.put(asmType, kotlinType, iv);
|
||||
iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
|
||||
iv.ifne(ne);
|
||||
}
|
||||
else if (asmType.getSort() == Type.DOUBLE) {
|
||||
thisPropertyValue.put(asmType, kotlinType, iv);
|
||||
otherPropertyValue.put(asmType, kotlinType, iv);
|
||||
iv.invokestatic("java/lang/Double", "compare", "(DD)I", false);
|
||||
iv.ifne(ne);
|
||||
}
|
||||
else {
|
||||
StackValue value = genEqualsForExpressionsOnStack(
|
||||
KtTokens.EQEQ, StackValue.onStack(asmType, kotlinType), StackValue.onStack(asmType, kotlinType)
|
||||
KtTokens.EQEQ, thisPropertyValue, otherPropertyValue
|
||||
);
|
||||
value.put(Type.BOOLEAN_TYPE, iv);
|
||||
iv.ifeq(ne);
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
inline class Z(val x: Int)
|
||||
inline class NZ1(val nz: Z?)
|
||||
inline class NZ2(val nz: NZ1)
|
||||
|
||||
fun box(): String {
|
||||
if (NZ2(NZ1(null)) != NZ2(NZ1(null))) throw AssertionError()
|
||||
if (NZ2(NZ1(Z(1))) != NZ2(NZ1(Z(1)))) throw AssertionError()
|
||||
if (NZ2(NZ1(null)) == NZ2(NZ1(Z(1)))) throw AssertionError()
|
||||
if (NZ2(NZ1(Z(1))) == NZ2(NZ1(null))) throw AssertionError()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// WITH_UNSIGNED
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
fun isZeroUInt(n: UInt?) = 0U == n
|
||||
fun isZeroULong(n: ULong?) = 0UL == n
|
||||
|
||||
fun box(): String {
|
||||
if (isZeroUInt(null)) throw AssertionError()
|
||||
if (isZeroUInt(1U)) throw AssertionError()
|
||||
if (!isZeroUInt(0U)) throw AssertionError()
|
||||
|
||||
if (isZeroULong(null)) throw AssertionError()
|
||||
if (isZeroULong(1UL)) throw AssertionError()
|
||||
if (!isZeroULong(0UL)) throw AssertionError()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// WITH_UNSIGNED
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
fun isZeroUInt(n: UInt?) = n == 0U
|
||||
fun isZeroULong(n: ULong?) = n == 0UL
|
||||
|
||||
fun box(): String {
|
||||
if (isZeroUInt(null)) throw AssertionError()
|
||||
if (isZeroUInt(1U)) throw AssertionError()
|
||||
if (!isZeroUInt(0U)) throw AssertionError()
|
||||
|
||||
if (isZeroULong(null)) throw AssertionError()
|
||||
if (isZeroULong(1UL)) throw AssertionError()
|
||||
if (!isZeroULong(0UL)) throw AssertionError()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+15
@@ -23882,6 +23882,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt")
|
||||
public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("evaluateConstructorOfUnsignedType.kt")
|
||||
public void testEvaluateConstructorOfUnsignedType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt");
|
||||
@@ -23907,6 +23912,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableUnsignedEqualsLiteral.kt")
|
||||
public void testNullableUnsignedEqualsLiteral() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("signedToUnsignedLiteralConversion.kt")
|
||||
public void testSignedToUnsignedLiteralConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt");
|
||||
|
||||
+15
@@ -23882,6 +23882,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt")
|
||||
public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("evaluateConstructorOfUnsignedType.kt")
|
||||
public void testEvaluateConstructorOfUnsignedType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt");
|
||||
@@ -23907,6 +23912,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableUnsignedEqualsLiteral.kt")
|
||||
public void testNullableUnsignedEqualsLiteral() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("signedToUnsignedLiteralConversion.kt")
|
||||
public void testSignedToUnsignedLiteralConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt");
|
||||
|
||||
+15
@@ -23887,6 +23887,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt")
|
||||
public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("evaluateConstructorOfUnsignedType.kt")
|
||||
public void testEvaluateConstructorOfUnsignedType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt");
|
||||
@@ -23912,6 +23917,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableUnsignedEqualsLiteral.kt")
|
||||
public void testNullableUnsignedEqualsLiteral() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("signedToUnsignedLiteralConversion.kt")
|
||||
public void testSignedToUnsignedLiteralConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt");
|
||||
|
||||
+15
@@ -21047,6 +21047,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt")
|
||||
public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("forEachIndexedInListOfUInts.kt")
|
||||
public void testForEachIndexedInListOfUInts() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/forEachIndexedInListOfUInts.kt");
|
||||
@@ -21067,6 +21072,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableUnsignedEqualsLiteral.kt")
|
||||
public void testNullableUnsignedEqualsLiteral() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("signedToUnsignedLiteralConversion.kt")
|
||||
public void testSignedToUnsignedLiteralConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt");
|
||||
|
||||
+15
@@ -22092,6 +22092,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt")
|
||||
public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("forEachIndexedInListOfUInts.kt")
|
||||
public void testForEachIndexedInListOfUInts() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/forEachIndexedInListOfUInts.kt");
|
||||
@@ -22112,6 +22117,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("literalEqualsNullableUnsigned.kt")
|
||||
public void testLiteralEqualsNullableUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableUnsignedEqualsLiteral.kt")
|
||||
public void testNullableUnsignedEqualsLiteral() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("signedToUnsignedLiteralConversion.kt")
|
||||
public void testSignedToUnsignedLiteralConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt");
|
||||
|
||||
Reference in New Issue
Block a user