Use correct lhs KotlinType & AsmType for is check generation

There were two problems:
  - For asm type `OBJECT_TYPE` was used, which can be wrong in case of
  inline classes, because it can be an underlying value of some inline class
  - For KotlinType, type from rhs was used
This commit is contained in:
Mikhail Zarechenskiy
2018-07-04 17:36:41 +03:00
parent 4f490ac264
commit 2939d9c8c6
7 changed files with 107 additions and 6 deletions
@@ -4487,21 +4487,29 @@ The "returned" value of try expression with no finally is either the last expres
return negated ? StackValue.not(value) : value;
}
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType kotlinType, boolean leaveExpressionOnStack) {
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType rhsKotlinType, boolean leaveExpressionOnStack) {
KotlinType lhsKotlinType = expressionToGen.kotlinType;
Type lhsBoxedType;
if (lhsKotlinType != null && InlineClassesUtilsKt.isInlineClassType(lhsKotlinType)) {
lhsBoxedType = typeMapper.mapTypeAsDeclaration(lhsKotlinType);
}
else {
lhsBoxedType = OBJECT_TYPE;
}
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
expressionToGen.put(OBJECT_TYPE, kotlinType, v);
expressionToGen.put(lhsBoxedType, expressionToGen.kotlinType, v);
if (leaveExpressionOnStack) {
v.dup();
}
Type type = boxType(typeMapper.mapTypeAsDeclaration(kotlinType));
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
Type type = boxType(typeMapper.mapTypeAsDeclaration(rhsKotlinType));
if (TypeUtils.isReifiedTypeParameter(rhsKotlinType)) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(rhsKotlinType, ReifiedTypeInliner.OperationKind.IS);
v.instanceOf(type);
return null;
}
CodegenUtilKt.generateIsCheck(v, kotlinType, type);
CodegenUtilKt.generateIsCheck(v, rhsKotlinType, type);
return null;
});
}
@@ -0,0 +1,68 @@
// !LANGUAGE: +InlineClasses
inline class AsAny(val a: Any?) {
fun myEq(other: Any?): Boolean {
return other is AsAny && other.a == a
}
}
inline class AsInt(val a: Int) {
fun myEq(other: Any?): Boolean {
return other is AsInt && other.a == a
}
}
inline fun <reified T> Any?.isCheck() = this is T
object Reference {
fun isNullable(a: AsAny) = a is AsAny?
fun isNotNullable(a: AsAny) = a is AsAny
fun isNullableNullable(a: AsAny?) = a is AsAny?
fun isNullableNotNullable(a: AsAny?) = a is AsAny
}
object Primitive {
fun isNullable(a: AsInt) = a is AsInt?
fun isNotNullable(a: AsInt) = a is AsInt
fun isNullableNullable(a: AsInt?) = a is AsInt?
fun isNullableNotNullable(a: AsInt?) = a is AsInt
}
fun box(): String {
val a = AsAny(42)
val b = AsAny(40 + 2)
if (!a.myEq(b)) return "Fail 1"
if (a.myEq(42)) return "Fail 2"
if (a.myEq("other")) return "Fail 3"
if (!Reference.isNullable(a)) return "Fail 4"
if (!Reference.isNotNullable(a)) return "Fail 5"
if (!Reference.isNullableNullable(a)) return "Fail 6"
if (!Reference.isNullableNullable(null)) return "Fail 7"
if (!Reference.isNullableNotNullable(a)) return "Fail 8"
if (Reference.isNullableNotNullable(null)) return "Fail 9"
val c = AsInt(42)
val d = AsInt(40 + 2)
if (!c.myEq(d)) return "Fail 10"
if (c.myEq(42)) return "Fail 11"
if (c.myEq("other")) return "Fail 12"
if (!Primitive.isNullable(c)) return "Fail 13"
if (!Primitive.isNotNullable(c)) return "Fail 14"
if (!Primitive.isNullableNullable(c)) return "Fail 15"
if (!Primitive.isNullableNullable(null)) return "Fail 16"
if (!Primitive.isNullableNotNullable(c)) return "Fail 17"
if (Primitive.isNullableNotNullable(null)) return "Fail 18"
if (!a.isCheck<AsAny>()) return "Fail 19"
if (!a.isCheck<AsAny?>()) return "Fail 20"
if (a.isCheck<AsInt>()) return "Fail 21"
if (!c.isCheck<AsInt>()) return "Fail 22"
if (!c.isCheck<AsInt?>()) return "Fail 23"
if (c.isCheck<AsAny>()) return "Fail 24"
return "OK"
}
@@ -11018,6 +11018,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("typeChecksForInlineClasses.kt")
public void testTypeChecksForInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
}
@TestMetadata("UIntArraySortExample.kt")
public void testUIntArraySortExample() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
@@ -11018,6 +11018,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("typeChecksForInlineClasses.kt")
public void testTypeChecksForInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
}
@TestMetadata("UIntArraySortExample.kt")
public void testUIntArraySortExample() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
@@ -11018,6 +11018,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("typeChecksForInlineClasses.kt")
public void testTypeChecksForInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
}
@TestMetadata("UIntArraySortExample.kt")
public void testUIntArraySortExample() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
@@ -9688,6 +9688,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("typeChecksForInlineClasses.kt")
public void testTypeChecksForInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
}
@TestMetadata("UIntArraySortExample.kt")
public void testUIntArraySortExample() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
@@ -9688,6 +9688,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
}
@TestMetadata("typeChecksForInlineClasses.kt")
public void testTypeChecksForInlineClasses() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
}
@TestMetadata("UIntArraySortExample.kt")
public void testUIntArraySortExample() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");