From f2520a9cb7faae7553c4ef5b42988793d62b41da Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Thu, 1 Jun 2023 10:06:01 +0200 Subject: [PATCH] [K/N] Rework is checks and as casts codegeneration ^KT-58707 ^KT-59022 --- ...LightTreeBlackBoxCodegenTestGenerated.java | 12 ++ .../FirPsiBlackBoxCodegenTestGenerated.java | 12 ++ .../testData/codegen/box/casts/kt50577.kt | 2 - .../testData/codegen/box/casts/kt58707.kt | 7 + .../testData/codegen/box/casts/kt59022.kt | 20 +++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 12 ++ .../LightAnalysisModeTestGenerated.java | 10 ++ .../js/test/JsCodegenBoxTestGenerated.java | 12 ++ .../fir/FirJsCodegenBoxTestGenerated.java | 12 ++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 12 ++ .../ir/IrJsES6CodegenBoxTestGenerated.java | 12 ++ .../kotlin/backend/konan/llvm/IrToBitcode.kt | 162 ++++++++++++------ .../backend/konan/lower/BridgesBuilding.kt | 4 +- .../konan/lower/TypeOperatorLowering.kt | 35 +--- .../FirNativeCodegenBoxTestGenerated.java | 12 ++ .../FirNativeCodegenBoxTestNoPLGenerated.java | 12 ++ .../NativeCodegenBoxTestGenerated.java | 12 ++ .../NativeCodegenBoxTestNoPLGenerated.java | 12 ++ .../test/IrCodegenBoxWasmTestGenerated.java | 10 ++ 21 files changed, 316 insertions(+), 90 deletions(-) create mode 100644 compiler/testData/codegen/box/casts/kt58707.kt create mode 100644 compiler/testData/codegen/box/casts/kt59022.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index b5f81f4983a..5bce30512c9 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -4961,6 +4961,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/casts/kt55005.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index bf51d32d7d2..f2a2624353c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -4961,6 +4961,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/casts/kt55005.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/compiler/testData/codegen/box/casts/kt50577.kt b/compiler/testData/codegen/box/casts/kt50577.kt index 4a2bccbe607..7f2f134fd04 100644 --- a/compiler/testData/codegen/box/casts/kt50577.kt +++ b/compiler/testData/codegen/box/casts/kt50577.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: NATIVE - abstract class A { abstract val x: Any diff --git a/compiler/testData/codegen/box/casts/kt58707.kt b/compiler/testData/codegen/box/casts/kt58707.kt new file mode 100644 index 00000000000..7d7c81ab3d8 --- /dev/null +++ b/compiler/testData/codegen/box/casts/kt58707.kt @@ -0,0 +1,7 @@ +interface A {} + +fun getA() = (object : A {}) as A + +fun box() : String { + return if (getA() is A) "OK" else "FAIL" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/casts/kt59022.kt b/compiler/testData/codegen/box/casts/kt59022.kt new file mode 100644 index 00000000000..f3135f4b6e8 --- /dev/null +++ b/compiler/testData/codegen/box/casts/kt59022.kt @@ -0,0 +1,20 @@ +// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, WASM +@file:Suppress("INCOMPATIBLE_TYPES", "UNCHECKED_CAST") + +fun unchecked(x: Any?) = x as T + +fun box() : String{ + if (unchecked(null) is Any) return "FAIL 1" + if (unchecked(null) is IntArray) return "FAIL 2" + try { + unchecked(null) as Any + return "FAIL 3" + } catch (e: NullPointerException) { + } + try { + unchecked(null) as IntArray + return "FAIL 4" + } catch (e: NullPointerException) { + } + return "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 48d41d9249e..bbdd73e4369 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -4757,6 +4757,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 08db33e491f..24421a33693 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -4961,6 +4961,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/casts/kt55005.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index 0ed885d9773..f665aae4197 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -4961,6 +4961,18 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/casts/kt55005.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index ba7a76b245b..d0ecbfd8501 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -4146,6 +4146,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { runTest("compiler/testData/codegen/box/casts/lambdaToUnitCast.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 473a13bdf0f..8a71d0078cf 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -3473,6 +3473,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java index b4ec851562b..ff4952f35e3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java @@ -3533,6 +3533,18 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest { runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 1e8c39b61a9..83be31684a8 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -3533,6 +3533,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java index d830f012f6d..f078d8cd94c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java @@ -3533,6 +3533,18 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index c38ad5feda5..596713cc5de 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -1185,7 +1185,7 @@ internal class CodeGeneratorVisitor( genCatchBlock() return // Remaining catch clauses are unreachable. } else { - val isInstance = genInstanceOf(exception, catch.catchParameter.type.getClass()!!) + val isInstance = genInstanceOfImpl(exception, catch.catchParameter.type.getClass()!!) val body = functionGenerationContext.basicBlock("catch", catch.startLocation) val nextCheck = functionGenerationContext.basicBlock("catchCheck", catch.endLocation) functionGenerationContext.condBr(isInstance, body, nextCheck) @@ -1519,73 +1519,123 @@ internal class CodeGeneratorVisitor( val dstClass = value.typeOperand.getClass() ?: error("No class for ${value.typeOperand.render()} from \n${functionGenerationContext.irFunction?.render()}") - val srcArg = evaluateExpression(value.argument, resultSlot) - assert(srcArg.type == codegen.kObjHeaderPtr) - - with(functionGenerationContext) { - ifThen(not(genInstanceOf(srcArg, dstClass))) { - if (dstClass.defaultType.isObjCObjectType()) { - val dstFullClassName = dstClass.fqNameWhenAvailable?.toString() ?: dstClass.name.toString() - callDirect( - context.ir.symbols.throwTypeCastException.owner, - listOf(srcArg, codegen.staticData.kotlinStringLiteral(dstFullClassName).llvm), - Lifetime.GLOBAL, - null - ) - } else { - val dstTypeInfo = functionGenerationContext.bitcast(llvm.int8PtrType, codegen.typeInfoValue(dstClass)) - callDirect( - context.ir.symbols.throwClassCastException.owner, - listOf(srcArg, dstTypeInfo), - Lifetime.GLOBAL, - null - ) + return genInstanceOf( + value, + dstClass, + resultSlot, + onSuperClassCast = { + it.takeIf { value.typeOperand.isNullable() } + }, + onNull = { + if (value.typeOperand.isNullable()) { + codegen.kNullObjHeaderPtr + } else { + callDirect( + context.ir.symbols.throwNullPointerException.owner, + listOf(), + Lifetime.GLOBAL, + null + ) + } + }, + onCheck = { argument, checkResult -> + with(functionGenerationContext) { + if (checkResult != kTrue) { + ifThen(not(checkResult)) { + if (dstClass.defaultType.isObjCObjectType()) { + val dstFullClassName = dstClass.fqNameWhenAvailable?.toString() ?: dstClass.name.toString() + callDirect( + context.ir.symbols.throwTypeCastException.owner, + listOf(argument, codegen.staticData.kotlinStringLiteral(dstFullClassName).llvm), + Lifetime.GLOBAL, + null + ) + } else { + val dstTypeInfo = functionGenerationContext.bitcast(llvm.int8PtrType, codegen.typeInfoValue(dstClass)) + callDirect( + context.ir.symbols.throwClassCastException.owner, + listOf(argument, dstTypeInfo), + Lifetime.GLOBAL, + null + ) + } + } + } + argument + } } - } - } - return srcArg + ) } //-------------------------------------------------------------------------// private fun evaluateInstanceOf(value: IrTypeOperatorCall): LLVMValueRef { context.log{"evaluateInstanceOf : ${ir2string(value)}"} - val type = value.typeOperand - val srcArg = evaluateExpression(value.argument) // Evaluate src expression. - - val bbExit = functionGenerationContext.basicBlock("instance_of_exit", value.startLocation) - val bbInstanceOf = functionGenerationContext.basicBlock("instance_of_notnull", value.startLocation) - val bbNull = functionGenerationContext.basicBlock("instance_of_null", value.startLocation) - - val condition = functionGenerationContext.icmpEq(srcArg, codegen.kNullObjHeaderPtr) - functionGenerationContext.condBr(condition, bbNull, bbInstanceOf) - - functionGenerationContext.positionAtEnd(bbNull) - val resultNull = if (type.isNullable()) kTrue else kFalse - functionGenerationContext.br(bbExit) - - functionGenerationContext.positionAtEnd(bbInstanceOf) - val typeOperandClass = value.typeOperand.getClass() - val resultInstanceOf = if (typeOperandClass != null) { - genInstanceOf(srcArg, typeOperandClass) - } else { - // E.g. when generating type operation with reified type parameter in the original body of inline function. - kTrue - // TODO: this code should be unreachable, recheck. - } - functionGenerationContext.br(bbExit) - val bbInstanceOfResult = functionGenerationContext.currentBlock - - functionGenerationContext.positionAtEnd(bbExit) - val result = functionGenerationContext.phi(llvm.int1Type) - functionGenerationContext.addPhiIncoming(result, bbNull to resultNull, bbInstanceOfResult to resultInstanceOf) - return result + return genInstanceOf( + value, + type.getClass() ?: context.ir.symbols.any.owner, + resultSlot = null, + onSuperClassCast = { arg -> + if (type.isNullable()) + kTrue + else + functionGenerationContext.icmpNe(arg, codegen.kNullObjHeaderPtr) + }, + onNull = { if (type.isNullable()) kTrue else kFalse }, + onCheck = { _, checkResult -> checkResult } + ) } //-------------------------------------------------------------------------// - private fun genInstanceOf(obj: LLVMValueRef, dstClass: IrClass) = with(functionGenerationContext) { + private inline fun genInstanceOf( + value: IrTypeOperatorCall, + dstClass: IrClass, + resultSlot: LLVMValueRef?, + onSuperClassCast: (LLVMValueRef) -> LLVMValueRef?, + onNull: () -> LLVMValueRef, + onCheck: (argument: LLVMValueRef, checkResult: LLVMValueRef) -> LLVMValueRef, + ) : LLVMValueRef { + val srcArg = evaluateExpression(value.argument, resultSlot) + require(srcArg.type == codegen.kObjHeaderPtr) + val isSuperClassCast = value.argument.type.isSubtypeOfClass(dstClass.symbol) + + if (isSuperClassCast) { + onSuperClassCast(srcArg)?.let { return it } + } + return with(functionGenerationContext) { + val bbInstanceOf = basicBlock("instance_of_notnull", value.startLocation) + val bbNull = basicBlock("instance_of_null", value.startLocation) + + + val condition = icmpEq(srcArg, codegen.kNullObjHeaderPtr) + condBr(condition, bbNull, bbInstanceOf) + + positionAtEnd(bbNull) + val resultNull = onNull() + val resultNullBB = currentBlock.takeIf { !isAfterTerminator() } + + positionAtEnd(bbInstanceOf) + val resultInstanceOf = onCheck(srcArg, if (isSuperClassCast) kTrue else genInstanceOfImpl(srcArg, dstClass)) + val resultInstanceOfBB = currentBlock.also { require(!isAfterTerminator()) } + + + if (resultNullBB == null) { + resultInstanceOf + } else { + val bbExit = basicBlock("instance_of_exit", value.startLocation) + positionAtEnd(bbExit) + appendingTo(resultInstanceOfBB) { br(bbExit) } + appendingTo(resultNullBB) { br(bbExit) } + val result = phi(value.type.toLLVMType(llvm)) + addPhiIncoming(result, resultNullBB to resultNull, resultInstanceOfBB to resultInstanceOf) + result + } + } + } + + private fun genInstanceOfImpl(obj: LLVMValueRef, dstClass: IrClass) = with(functionGenerationContext) { if (dstClass.defaultType.isObjCObjectType()) { genInstanceOfObjC(obj, dstClass) } else with(VirtualTablesLookup) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt index 8956939215a..e56fe9dfe6f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt @@ -272,7 +272,9 @@ private fun IrBlockBodyBuilder.buildTypeSafeBarrier(function: IrFunction, // But let's keep it simple here for now; JVM backend doesn't do this anyway. if (!type.isNullableAny()) { - +returnIfBadType(irGet(valueParameters[i]), type, + // Here, we can't trust value parameter type until we check it, because of @UnsafeVariance + // So we add implicit cast to avoid type check optimization + +returnIfBadType(irImplicitCast(irGet(valueParameters[i]), context.irBuiltIns.anyNType), type, if (typeSafeBarrierDescription == SpecialGenericSignatures.TypeSafeBarrierDescription.MAP_GET_OR_DEFAULT) irGet(valueParameters[2]) else irConst(typeSafeBarrierDescription.defaultValue) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TypeOperatorLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TypeOperatorLowering.kt index b4c3d1c4c7e..856ffd68c52 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TypeOperatorLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TypeOperatorLowering.kt @@ -55,37 +55,10 @@ internal class TypeOperatorLowering(val context: CommonBackendContext) : FileLow private fun lowerCast(expression: IrTypeOperatorCall): IrExpression { builder.at(expression) val typeOperand = expression.typeOperand.erasure() - -// assert (!TypeUtils.hasNullableSuperType(typeOperand)) // So that `isNullable()` <=> `isMarkedNullable`. - - // TODO: consider the case when expression type is wrong e.g. due to generics-related unchecked casts. - - return when { - expression.argument.type.isSubtypeOf(typeOperand, context.typeSystem) -> expression.argument - - expression.argument.type.isNullable() -> { - with(builder) { - irLetS(expression.argument) { argument -> - irIfThenElse( - type = expression.type, - condition = irEqeqeq(irGet(argument.owner), irNull()), - - thenPart = if (typeOperand.isNullable()) - irNull() - else - irCall(this@TypeOperatorLowering.context.ir.symbols.throwNullPointerException.owner), - - elsePart = irAs(irGet(argument.owner), typeOperand.makeNotNull()) - ) - } - } - } - - typeOperand.isMarkedNullable() -> builder.irAs(expression.argument, typeOperand.makeNotNull()) - - typeOperand == expression.typeOperand -> expression - - else -> builder.irAs(expression.argument, typeOperand) + return if (typeOperand == expression.typeOperand) { + expression + } else { + builder.irAs(expression.argument, typeOperand) } } diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java index 094d40f8f13..57b20184d68 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java @@ -3646,6 +3646,18 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java index 2d1e6cdba67..4a887eb8228 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java @@ -3724,6 +3724,18 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index f7f19c440bb..f2a31eed3fa 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -3608,6 +3608,18 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java index 3c636b674c0..c20b67ebb7b 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java @@ -3647,6 +3647,18 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @Test + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java index ac802c0bcf0..783c0bf1390 100644 --- a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java +++ b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java @@ -3111,6 +3111,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @TestMetadata("kt58707.kt") + public void testKt58707() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt58707.kt"); + } + + @TestMetadata("kt59022.kt") + public void testKt59022() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt59022.kt"); + } + @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { runTest("compiler/testData/codegen/box/casts/lambdaToUnitCast.kt");