Inline: Fix operand stack type verify error

This is a proposal to fix KT-49364.
Operand stack type verification happens before `checkcast`
is executed. When we implicitly cast an inline class
to a non-inline type, if type of stack value is not subtype
of the target, then coercing is necessary.
This commit is contained in:
Xin Wang
2022-08-23 22:47:39 +08:00
committed by teamcity
parent cc5f65be1e
commit 0eadf35132
4 changed files with 38 additions and 0 deletions
@@ -21287,6 +21287,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inlineClasses/genericVararg2ndConstructor.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("implicitCastToNonValueClassType.kt")
public void testImplicitCastToNonValueClassType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/implicitCastToNonValueClassType.kt");
}
@Test
@TestMetadata("initBlock.kt")
public void testInitBlock() throws Exception {
@@ -38,6 +38,13 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val
if (isFromTypeUnboxed && !isToTypeUnboxed) {
val boxed = typeMapper.mapType(erasedSourceType, TypeMappingMode.CLASS_DECLARATION)
StackValue.boxInlineClass(type, boxed, erasedSourceType.isNullable(), mv)
if (typeMapper.mapType(erasedTargetType) == target) {
if (!erasedSourceType.isSubtypeOf(erasedTargetType, codegen.context.typeSystem)) {
StackValue.coerce(boxed, target, mv, false)
}
}
return
}
if (!isFromTypeUnboxed && isToTypeUnboxed) {
@@ -0,0 +1,19 @@
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
fun box(): String {
try {
val a:ULong = 1u
a as Int
func(a)
} catch (e: ClassCastException) {
return "OK"
}
return "FAIL"
}
fun func(para: Int) {}
// CHECK_BYTECODE_TEXT
// 1 CHECKCAST java/lang/Integer
// 1 L2I
@@ -21287,6 +21287,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/genericVararg2ndConstructor.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("implicitCastToNonValueClassType.kt")
public void testImplicitCastToNonValueClassType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/implicitCastToNonValueClassType.kt");
}
@Test
@TestMetadata("initBlock.kt")
public void testInitBlock() throws Exception {