From 6993b86d3b6d1f93f102244ae451fa1072fe1e03 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 28 Jun 2021 17:14:22 +0300 Subject: [PATCH] [IR] Fix `IrCapturedType` equals/hashCode It could lead to SOE if CT has itself as superType - fix KT-47424 --- .../runners/ir/Fir2IrTextTestGenerated.java | 6 + .../kotlin/ir/types/impl/IrTypeBase.kt | 9 +- compiler/testData/ir/irText/classes/47424.kt | 23 +++ .../testData/ir/irText/classes/47424.kt.txt | 33 +++++ compiler/testData/ir/irText/classes/47424.txt | 132 ++++++++++++++++++ .../test/runners/ir/IrTextTestGenerated.java | 6 + .../kotlin/ir/KlibTextTestCaseGenerated.java | 5 + 7 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/ir/irText/classes/47424.kt create mode 100644 compiler/testData/ir/irText/classes/47424.kt.txt create mode 100644 compiler/testData/ir/irText/classes/47424.txt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index 5c36a8c66ed..636dfd134ff 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -29,6 +29,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { @TestMetadata("compiler/testData/ir/irText/classes") @TestDataPath("$PROJECT_ROOT") public class Classes { + @Test + @TestMetadata("47424.kt") + public void test47424() throws Exception { + runTest("compiler/testData/ir/irText/classes/47424.kt"); + } + @Test @TestMetadata("abstractMembers.kt") public void testAbstractMembers() throws Exception { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt index edc84085d34..68ab9945256 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt @@ -107,15 +107,10 @@ class IrCapturedType( return other is IrCapturedType && captureStatus == other.captureStatus && lowerType == other.lowerType - && constructor.argument == other.constructor.argument - && constructor.typeParameter == other.constructor.typeParameter - && constructor.superTypes == other.constructor.superTypes + && constructor === other.constructor } override fun hashCode(): Int { - return (((captureStatus.hashCode() * 31 - + (lowerType?.hashCode() ?: 0)) * 31 - + constructor.argument.hashCode()) * 31 - + constructor.typeParameter.hashCode()) + constructor.superTypes.hashCode() + return (captureStatus.hashCode() * 31 + (lowerType?.hashCode() ?: 0)) * 31 + constructor.hashCode() } } \ No newline at end of file diff --git a/compiler/testData/ir/irText/classes/47424.kt b/compiler/testData/ir/irText/classes/47424.kt new file mode 100644 index 00000000000..91195065f3e --- /dev/null +++ b/compiler/testData/ir/irText/classes/47424.kt @@ -0,0 +1,23 @@ +// FIR_IDENTICAL +package com.example + + +interface Aa + +interface Ab> : Aa + + +interface Ba + +interface Bb> : Ab, Ba + + +interface Ca { + val b: Ba +} + +interface Cb { + val b: Bb<*> +} + +interface C : Cb, Ca \ No newline at end of file diff --git a/compiler/testData/ir/irText/classes/47424.kt.txt b/compiler/testData/ir/irText/classes/47424.kt.txt new file mode 100644 index 00000000000..f167f1009c1 --- /dev/null +++ b/compiler/testData/ir/irText/classes/47424.kt.txt @@ -0,0 +1,33 @@ +package com.example + +interface Aa { + +} + +interface Ab> : Aa { + +} + +interface Ba { + +} + +interface Bb> : Ab, Ba { + +} + +interface Ca { + abstract val b: Ba + abstract get + +} + +interface Cb { + abstract val b: Bb<*> + abstract get + +} + +interface C : Cb, Ca { + +} diff --git a/compiler/testData/ir/irText/classes/47424.txt b/compiler/testData/ir/irText/classes/47424.txt new file mode 100644 index 00000000000..8998fb458e8 --- /dev/null +++ b/compiler/testData/ir/irText/classes/47424.txt @@ -0,0 +1,132 @@ +FILE fqName:com.example fileName:/47424.kt + CLASS INTERFACE name:Aa modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.Aa + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Ab modality:ABSTRACT visibility:public superTypes:[com.example.Aa] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.Ab + TYPE_PARAMETER name:T index:0 variance: superTypes:[com.example.Ab] + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in com.example.Aa + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in com.example.Aa + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in com.example.Aa + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Ba modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.Ba + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Bb modality:ABSTRACT visibility:public superTypes:[com.example.Ab; com.example.Ba] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.Bb + TYPE_PARAMETER name:T index:0 variance: superTypes:[com.example.Bb] + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in com.example.Ab + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in com.example.Ba + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in com.example.Ab + public open fun hashCode (): kotlin.Int [fake_override] declared in com.example.Ba + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in com.example.Ab + public open fun toString (): kotlin.String [fake_override] declared in com.example.Ba + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Ca modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.Ca + PROPERTY name:b visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:com.example.Ca) returnType:com.example.Ba + correspondingProperty: PROPERTY name:b visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:com.example.Ca + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Cb modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.Cb + PROPERTY name:b visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:com.example.Cb) returnType:com.example.Bb<*> + correspondingProperty: PROPERTY name:b visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:com.example.Cb + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:C modality:ABSTRACT visibility:public superTypes:[com.example.Cb; com.example.Ca] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:com.example.C + PROPERTY FAKE_OVERRIDE name:b visibility:public modality:ABSTRACT [fake_override,val] + overridden: + public abstract b: com.example.Bb<*> [val] + public abstract b: com.example.Ba [val] + FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:com.example.Cb) returnType:com.example.Bb<*> [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:b visibility:public modality:ABSTRACT [fake_override,val] + overridden: + public abstract fun (): com.example.Bb<*> declared in com.example.Cb + public abstract fun (): com.example.Ba declared in com.example.Ca + $this: VALUE_PARAMETER name: type:com.example.Cb + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in com.example.Cb + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in com.example.Ca + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in com.example.Cb + public open fun hashCode (): kotlin.Int [fake_override] declared in com.example.Ca + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in com.example.Cb + public open fun toString (): kotlin.String [fake_override] declared in com.example.Ca + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index 319340f021f..80a01a3fa00 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -29,6 +29,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { @TestMetadata("compiler/testData/ir/irText/classes") @TestDataPath("$PROJECT_ROOT") public class Classes { + @Test + @TestMetadata("47424.kt") + public void test47424() throws Exception { + runTest("compiler/testData/ir/irText/classes/47424.kt"); + } + @Test @TestMetadata("abstractMembers.kt") public void testAbstractMembers() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java index b9d0379571d..297ee99ea8c 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/ir/KlibTextTestCaseGenerated.java @@ -38,6 +38,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase { KotlinTestUtils.runTest(this::doTest, TargetBackend.JS_IR, testDataFilePath); } + @TestMetadata("47424.kt") + public void test47424() throws Exception { + runTest("compiler/testData/ir/irText/classes/47424.kt"); + } + @TestMetadata("abstractMembers.kt") public void testAbstractMembers() throws Exception { runTest("compiler/testData/ir/irText/classes/abstractMembers.kt");