diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 36bc112923d..eb2861c81f8 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -645,6 +645,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid return valuePhi } + //-------------------------------------------------------------------------// private fun evaluateExpressionAndJump(expression: IrExpression, destination: ContinuationBlock) { @@ -1242,9 +1243,29 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid val type = value.typeOperand val srcArg = evaluateExpression(codegen.newVar(), value.argument)!! // Evaluate src expression. - return genInstanceOf(tmpVariableName, srcArg, type) + val bbNull = codegen.basicBlock() + val bbInstanceOf = codegen.basicBlock() + val bbExit = codegen.basicBlock() + + val condition = codegen.icmpEq(srcArg, codegen.kNullObjHeaderPtr, codegen.newVar()) + codegen.condBr(condition, bbNull, bbInstanceOf) + + codegen.positionAtEnd(bbNull) + val resultNull = if (TypeUtils.isNullableType(type)) kTrue else kFalse + codegen.br(bbExit) + + codegen.positionAtEnd(bbInstanceOf) + val resultInstanceOf = genInstanceOf(tmpVariableName, srcArg, type) + codegen.br(bbExit) + + codegen.positionAtEnd(bbExit) + val result = codegen.phi(kBoolean, codegen.newVar()) + codegen.addPhiIncoming(result, bbNull to resultNull, bbInstanceOf to resultInstanceOf) + return result } + //-------------------------------------------------------------------------// + private fun genInstanceOf(tmpVariableName: String, obj: LLVMValueRef, type: KotlinType): LLVMValueRef { val dstDescriptor = TypeUtils.getClassDescriptor(type) // Get class descriptor for dst type. val dstTypeInfo = codegen.typeInfoValue(dstDescriptor!!) // Get TypeInfo for dst type. diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 690bbcdd632..bb3c47f5f3a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -115,6 +115,7 @@ internal val ContextUtils.kObjHeaderPtrPtr: LLVMTypeRef internal val ContextUtils.kTypeInfoPtr: LLVMTypeRef get() = pointerType(kTypeInfo) internal val kInt1 = LLVMInt1Type()!! +internal val kBoolean = kInt1 internal val kInt8Ptr = pointerType(int8Type) internal val kInt8PtrPtr = pointerType(kInt8Ptr) internal val kImmInt32One = Int32(1).llvm