From f5a78213b25beecd83eb3bcffa57eea4dfde7ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Tue, 30 Apr 2019 14:01:17 +0200 Subject: [PATCH] Fix type of super --- .../kotlin/backend/jvm/intrinsics/Clone.kt | 18 ++++++------- .../generators/ArgumentsGenerationUtils.kt | 3 ++- .../ir/irText/classes/qualifiedSuperCalls.txt | 8 +++--- .../ir/irText/classes/superCalls.fir.txt | 26 +++++++++---------- .../testData/ir/irText/classes/superCalls.kt | 2 ++ .../testData/ir/irText/classes/superCalls.txt | 24 ++++++++++------- 6 files changed, 43 insertions(+), 38 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Clone.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Clone.kt index 20f7b40c8ad..68474247221 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Clone.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Clone.kt @@ -16,21 +16,19 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics -import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.codegen.* +import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression -import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.resolve.jvm.AsmTypes -import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.Opcodes object Clone : IntrinsicMethod() { - - override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction { - return IrIntrinsicFunction.create(expression, signature.newReturnType(AsmTypes.OBJECT_TYPE), context) { - val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL - it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false) - } + override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo) = with(codegen) { + val result = expression.dispatchReceiver!!.accept(this, data).materialized + assert(!AsmUtil.isPrimitive(result.type)) { "clone() of primitive type" } + val opcode = if (expression is IrCall && expression.superQualifier != null) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL + mv.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false) + MaterialValue(codegen.mv, AsmTypes.OBJECT_TYPE) } - } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index 894e7905aa3..c1b0fb7966e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -136,7 +136,8 @@ private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverVal val expressionReceiver = receiver as? ExpressionReceiver ?: throw AssertionError("'this' or 'super' receiver should be an expression receiver") val ktReceiver = expressionReceiver.expression - return generateThisReceiver(ktReceiver.startOffsetSkippingComments, ktReceiver.endOffset, expressionReceiver.type, classDescriptor) + val type = if (receiver is SuperCallReceiverValue) receiver.thisType else expressionReceiver.type + return generateThisReceiver(ktReceiver.startOffsetSkippingComments, ktReceiver.endOffset, type, classDescriptor) } fun StatementGenerator.generateBackingFieldReceiver( diff --git a/compiler/testData/ir/irText/classes/qualifiedSuperCalls.txt b/compiler/testData/ir/irText/classes/qualifiedSuperCalls.txt index 0a353bb53e3..9c4df75bfa9 100644 --- a/compiler/testData/ir/irText/classes/qualifiedSuperCalls.txt +++ b/compiler/testData/ir/irText/classes/qualifiedSuperCalls.txt @@ -62,9 +62,9 @@ FILE fqName: fileName:/qualifiedSuperCalls.kt $this: VALUE_PARAMETER name: type:.CBoth BLOCK_BODY CALL 'public open fun foo (): kotlin.Unit declared in .ILeft' superQualifier='CLASS INTERFACE name:ILeft modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit origin=null - $this: GET_VAR ': .CBoth declared in .CBoth.foo' type=.ILeft origin=null + $this: GET_VAR ': .CBoth declared in .CBoth.foo' type=.CBoth origin=null CALL 'public open fun foo (): kotlin.Unit declared in .IRight' superQualifier='CLASS INTERFACE name:IRight modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit origin=null - $this: GET_VAR ': .CBoth declared in .CBoth.foo' type=.IRight origin=null + $this: GET_VAR ': .CBoth declared in .CBoth.foo' type=.CBoth origin=null PROPERTY name:bar visibility:public modality:OPEN [val] FUN name: visibility:public modality:OPEN <> ($this:.CBoth) returnType:kotlin.Int correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [val] @@ -76,9 +76,9 @@ FILE fqName: fileName:/qualifiedSuperCalls.kt RETURN type=kotlin.Nothing from='public open fun (): kotlin.Int declared in .CBoth' CALL 'public final fun plus (other: kotlin.Int): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=PLUS $this: CALL 'public open fun (): kotlin.Int declared in .ILeft' superQualifier='CLASS INTERFACE name:ILeft modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR ': .CBoth declared in .CBoth.' type=.ILeft origin=null + $this: GET_VAR ': .CBoth declared in .CBoth.' type=.CBoth origin=null other: CALL 'public open fun (): kotlin.Int declared in .IRight' superQualifier='CLASS INTERFACE name:IRight modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR ': .CBoth declared in .CBoth.' type=.IRight origin=null + $this: GET_VAR ': .CBoth declared in .CBoth.' type=.CBoth origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .ILeft diff --git a/compiler/testData/ir/irText/classes/superCalls.fir.txt b/compiler/testData/ir/irText/classes/superCalls.fir.txt index bfbc2afb21b..54186fc09d8 100644 --- a/compiler/testData/ir/irText/classes/superCalls.fir.txt +++ b/compiler/testData/ir/irText/classes/superCalls.fir.txt @@ -19,15 +19,16 @@ FILE fqName: fileName:/superCalls.kt RETURN type=kotlin.Nothing from='public open fun (): kotlin.String declared in .Base' GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:bar type:kotlin.String visibility:public [final] ' type=kotlin.String origin=null receiver: GET_VAR ': .Base declared in .Base.' type=.Base origin=null - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + FUN name:hashCode visibility:public modality:OPEN <> ($this:.Base) returnType:kotlin.Int + $this: VALUE_PARAMETER name: type:.Base + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun hashCode (): kotlin.Int declared in .Base' + CALL 'public open fun hashCode (): kotlin.Int declared in kotlin.Any' type=kotlin.Int origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean 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 - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String overridden: public open fun toString (): kotlin.String declared in kotlin.Any @@ -49,17 +50,16 @@ FILE fqName: fileName:/superCalls.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .Derived' CALL 'public open fun (): kotlin.String declared in .Base' type=kotlin.String origin=null - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:.Base) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in .Base + $this: VALUE_PARAMETER name: type:.Base + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean 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 - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any - diff --git a/compiler/testData/ir/irText/classes/superCalls.kt b/compiler/testData/ir/irText/classes/superCalls.kt index 69039a1bd16..516850740da 100644 --- a/compiler/testData/ir/irText/classes/superCalls.kt +++ b/compiler/testData/ir/irText/classes/superCalls.kt @@ -2,6 +2,8 @@ open class Base { open fun foo() {} open val bar: String = "" + + override fun hashCode() = super.hashCode() } class Derived : Base() { diff --git a/compiler/testData/ir/irText/classes/superCalls.txt b/compiler/testData/ir/irText/classes/superCalls.txt index 6b919302d3a..a8861ada933 100644 --- a/compiler/testData/ir/irText/classes/superCalls.txt +++ b/compiler/testData/ir/irText/classes/superCalls.txt @@ -19,15 +19,19 @@ FILE fqName: fileName:/superCalls.kt RETURN type=kotlin.Nothing from='public open fun (): kotlin.String declared in .Base' GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:bar type:kotlin.String visibility:public [final] ' type=kotlin.String origin=null receiver: GET_VAR ': .Base declared in .Base.' type=.Base origin=null - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + FUN name:hashCode visibility:public modality:OPEN <> ($this:.Base) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:.Base + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun hashCode (): kotlin.Int declared in .Base' + CALL 'public open fun hashCode (): kotlin.Int declared in kotlin.Any' superQualifier='CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public superTypes:[]' type=kotlin.Int origin=null + $this: GET_VAR ': .Base declared in .Base.hashCode' type=.Base origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean 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 - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String overridden: public open fun toString (): kotlin.String declared in kotlin.Any @@ -44,7 +48,7 @@ FILE fqName: fileName:/superCalls.kt $this: VALUE_PARAMETER name: type:.Derived BLOCK_BODY CALL 'public open fun foo (): kotlin.Unit declared in .Base' superQualifier='CLASS CLASS name:Base modality:OPEN visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit origin=null - $this: GET_VAR ': .Derived declared in .Derived.foo' type=.Base origin=null + $this: GET_VAR ': .Derived declared in .Derived.foo' type=.Derived origin=null PROPERTY name:bar visibility:public modality:OPEN [val] FUN name: visibility:public modality:OPEN <> ($this:.Derived) returnType:kotlin.String correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [val] @@ -54,16 +58,16 @@ FILE fqName: fileName:/superCalls.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun (): kotlin.String declared in .Derived' CALL 'public open fun (): kotlin.String declared in .Base' superQualifier='CLASS CLASS name:Base modality:OPEN visibility:public superTypes:[kotlin.Any]' type=kotlin.String origin=GET_PROPERTY - $this: GET_VAR ': .Derived declared in .Derived.' type=.Base origin=null + $this: GET_VAR ': .Derived declared in .Derived.' type=.Derived origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .Base $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 + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:.Base) returnType:kotlin.Int overridden: public open fun hashCode (): kotlin.Int declared in .Base - $this: VALUE_PARAMETER name: type:kotlin.Any + $this: VALUE_PARAMETER name: type:.Base FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String overridden: public open fun toString (): kotlin.String declared in .Base