JVM IR: fix HashCode intrinsic for generics substituted with primitives

The problem here was that although the IR type of the expression was
primitive, the type of the actual expression in the bytecode generated
after type erasure was `Ljava/lang/Object;`, and we were trying to call
a non-existing method `Object.hashCode(Object)`.

 #KT-41669 Fixed
This commit is contained in:
Alexander Udalov
2020-09-03 20:09:49 +02:00
parent c46c80822c
commit 3a5d0ab427
9 changed files with 49 additions and 2 deletions
@@ -14878,6 +14878,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");
@@ -33,9 +33,10 @@ object HashCode : IntrinsicMethod() {
val result = receiver.accept(this, data).materialized()
val target = context.state.target
when {
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD || irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
AsmUtil.genHashCode(mv, mv, result.type, target)
target == JvmTarget.JVM_1_6 -> {
target == JvmTarget.JVM_1_6 || !AsmUtil.isPrimitive(result.type) -> {
result.materializeAtBoxed(receiver.type)
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
@@ -0,0 +1,11 @@
// JVM_TARGET: 1.8
class A<T> {
fun id(x: T): T = x
}
fun foo(f: A<Boolean>): Int =
f.id(true).hashCode()
fun box(): String =
if (foo(A<Boolean>()) == true.hashCode()) "OK" else "Fail"
@@ -16103,6 +16103,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");
@@ -16103,6 +16103,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");
@@ -14878,6 +14878,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");
@@ -12893,6 +12893,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");
@@ -12893,6 +12893,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");
@@ -12958,6 +12958,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/ir/genericCompanion.kt");
}
@TestMetadata("hashCodeOnGenericSubstitutedWithPrimitive.kt")
public void testHashCodeOnGenericSubstitutedWithPrimitive() throws Exception {
runTest("compiler/testData/codegen/box/ir/hashCodeOnGenericSubstitutedWithPrimitive.kt");
}
@TestMetadata("kt25405.kt")
public void testKt25405() throws Exception {
runTest("compiler/testData/codegen/box/ir/kt25405.kt");