JVM_IR: Serialization: do not mess with return types of call expressions

If return type of IrConstructor is different from containing class, we will
generate call to wrong <init> method, leading to VerifyError.
If we do not specify the type of irNull, it, by default, will be Nothing?,
when really we need Any?. This leads to CCE: cannot cast to Void at runtime.
This commit is contained in:
Ilmir Usmanov
2020-03-18 20:00:16 +01:00
parent d06c87207c
commit be87d5fab5
2 changed files with 5 additions and 4 deletions
@@ -499,7 +499,8 @@ interface IrBuilderExtension {
null, compilerContext.symbolTable.referenceConstructor(nullableSerializerClass.descriptor.constructors.toList().first()),
typeArguments = listOf(type.makeNotNullable().toIrType()),
valueArguments = listOf(expression),
returnTypeHint = wrapIrTypeIntoKSerializerIrType(module, type.toIrType())
// Return type should not be different from declared class, otherwise, we will call wrong <init> method on runtime.
returnTypeHint = null
)
else
expression
@@ -656,8 +657,8 @@ interface IrBuilderExtension {
} else {
compilerContext.symbolTable.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!)
}
val returnType = wrapIrTypeIntoKSerializerIrType(module, thisIrType)
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnType)
// Return type should not be different from declared class, otherwise, we will call wrong <init> method on runtime.
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = null)
}
}
@@ -311,7 +311,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
else -> null
}
return if (defaultPrimitive == null)
irNull() to (compilerContext.builtIns.nullableAnyType)
irNull(compilerContext.irBuiltIns.anyNType) to (compilerContext.builtIns.nullableAnyType)
else
defaultPrimitive to kType
}