Fix CCE when unboxed inline class receiver is passed to inline function

Initial problem is started in `capturedBoundReferenceReceiver` method
 where we assume that bound receiver is captured for usual call.

 Note that if method is inline then we don't pass actual name reference
 receiver, but pass special CAPTURED_RECEIVER_FIELD, which is then
 is used to find special instructions during inline and fold several
 instructions in `foldFieldAccessChainIfNeeded`.

 As a result, we got unboxed reference receiver for inline call, which
 caused CCE and to fix it we should box receiver one more time during
 inline

 #KT-28188 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2018-11-14 02:21:03 +03:00
parent 99d8f2eb0c
commit 35fb3ba096
8 changed files with 105 additions and 2 deletions
@@ -748,9 +748,16 @@ class PsiInlineCodegen(
val receiverValue = getBoundCallableReferenceReceiver(argumentExpression)
if (receiverValue != null) {
val receiver = codegen.generateReceiverValue(receiverValue, false)
val receiverKotlinType = receiver.kotlinType
val boxedReceiver =
if (receiverKotlinType != null)
receiver.type.boxReceiverForBoundReference(receiverKotlinType, state)
else
receiver.type.boxReceiverForBoundReference()
putClosureParametersOnStack(
lambdaInfo,
StackValue.coercion(receiver, receiver.type.boxReceiverForBoundReference(), null)
StackValue.coercion(receiver, boxedReceiver, receiverKotlinType)
)
}
} else {
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.*
import org.jetbrains.kotlin.codegen.binding.MutableClosure
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
@@ -173,7 +175,11 @@ class DefaultLambda(
}
}
fun Type.boxReceiverForBoundReference() = AsmUtil.boxType(this)
fun Type.boxReceiverForBoundReference() =
AsmUtil.boxType(this)
fun Type.boxReceiverForBoundReference(kotlinType: KotlinType, state: GenerationState) =
AsmUtil.boxType(this, kotlinType, state)
abstract class ExpressionLambda(protected val typeMapper: KotlinTypeMapper, isCrossInline: Boolean) : LambdaInfo(isCrossInline) {