From be87d5fab5817fb8e2bcac1d8c3ea2cc217734e5 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 18 Mar 2020 20:00:16 +0100 Subject: [PATCH] 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 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. --- .../serialization/compiler/backend/ir/GeneratorHelpers.kt | 7 ++++--- .../compiler/backend/ir/SerializerIrGenerator.kt | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt index e0f3bda6d8d..2323a144ab4 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt @@ -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 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 method on runtime. + return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = null) } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt index 1a445308317..d017df931b0 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt @@ -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 }