Fix problem with empty vararg of boxed primitives in JVM_IR

When calling a generic Java generic method with vararg parameters with empty
vararg, incorrect array creation instruction was generated for primitive type:
NEWARRAY T_INT instead of ANEWARRAY java/lang/Integer. Here for Java method

  public static <T> void takesVarargOfT(T x1, T... xs) {}

corresponding vararg parameter was considered to be of type 'Array<T>?',
which is not a non-null array type, so, NewArray intrinsic failed to generate
proper bytecode.
This commit is contained in:
Dmitry Petrov
2019-12-27 16:12:16 +03:00
parent 0667ee9796
commit 98bf0e278f
7 changed files with 67 additions and 2 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.getArrayElementType
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.types.isNullableArray
import org.jetbrains.org.objectweb.asm.Type
object NewArray : IntrinsicMethod() {
@@ -19,7 +20,7 @@ object NewArray : IntrinsicMethod() {
codegen.gen(expression.getValueArgument(0)!!, Type.INT_TYPE, codegen.context.irBuiltIns.intType, data)
return with(codegen) {
val elementIrType = expression.type.getArrayElementType(context.irBuiltIns)
if (expression.type.isArray()) {
if (expression.type.isArray() || expression.type.isNullableArray()) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(elementIrType, ReifiedTypeInliner.OperationKind.NEW_ARRAY)
mv.newarray(typeMapper.boxType(elementIrType))
} else {
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.makeNotNull
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -56,7 +57,7 @@ private class VarargLowering(val context: JvmBackendContext) : FileLoweringPass,
val parameter = function.owner.valueParameters[i]
if (parameter.varargElementType != null && !parameter.hasDefaultValue()) {
// Compute the correct type for the array argument.
val arrayType = parameter.type.substitute(expression.typeSubstitutionMap)
val arrayType = parameter.type.substitute(expression.typeSubstitutionMap).makeNotNull()
expression.putValueArgument(i, createBuilder().irArrayOf(arrayType))
}
}