[FIR] KT-57655: Add the missing condition

^KT-57655 Fixed
This commit is contained in:
Nikolay Lunyak
2023-04-20 10:23:55 +03:00
committed by Space Team
parent c4d5332251
commit 931894ab3c
21 changed files with 237 additions and 122 deletions
@@ -1,23 +0,0 @@
// ISSUE: KT-57655
// !LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
// ALLOW_KOTLIN_PACKAGE
// WITH_STDLIB
// DUMP_IR
// FILE: annotation.kt
package kotlin.internal
annotation class ImplicitIntegerCoercion
// FILE: test.kt
import kotlin.internal.ImplicitIntegerCoercion
fun test(@ImplicitIntegerCoercion x: UInt) = x as UInt
fun box(): String = when {
test(5) != 5.toUInt() -> "Fail: test(5)"
test(x = 5) != 5.toUInt() -> "Fail: test(x = 5)"
else -> "OK"
}
@@ -0,0 +1,80 @@
FILE fqName:kotlin.internal fileName:/annotation.kt
CLASS ANNOTATION_CLASS name:ImplicitIntegerCoercion modality:OPEN visibility:public superTypes:[kotlin.Annotation]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:kotlin.internal.ImplicitIntegerCoercion
CONSTRUCTOR visibility:public <> () returnType:kotlin.internal.ImplicitIntegerCoercion [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:ImplicitIntegerCoercion modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FILE fqName:<root> fileName:/test.kt
FUN name:testInt visibility:public modality:FINAL <> (x:kotlin.UInt) returnType:kotlin.UInt
VALUE_PARAMETER name:x index:0 type:kotlin.UInt
annotations:
ImplicitIntegerCoercion
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testInt (x: kotlin.UInt): kotlin.UInt declared in <root>'
TYPE_OP type=kotlin.UInt origin=CAST typeOperand=kotlin.UInt
GET_VAR 'x: kotlin.UInt declared in <root>.testInt' type=kotlin.UInt origin=null
FUN name:testLong visibility:public modality:FINAL <> (x:kotlin.ULong) returnType:kotlin.ULong
VALUE_PARAMETER name:x index:0 type:kotlin.ULong
annotations:
ImplicitIntegerCoercion
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testLong (x: kotlin.ULong): kotlin.ULong declared in <root>'
TYPE_OP type=kotlin.ULong origin=CAST typeOperand=kotlin.ULong
GET_VAR 'x: kotlin.ULong declared in <root>.testLong' type=kotlin.ULong origin=null
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
WHEN type=kotlin.String origin=WHEN
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun testInt (x: kotlin.UInt): kotlin.UInt declared in <root>' type=kotlin.UInt origin=null
x: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
arg1: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
then: CONST String type=kotlin.String value="Fail: testInt(5)"
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun testInt (x: kotlin.UInt): kotlin.UInt declared in <root>' type=kotlin.UInt origin=null
x: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
arg1: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
then: CONST String type=kotlin.String value="Fail: testInt(x = 5)"
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun testLong (x: kotlin.ULong): kotlin.ULong declared in <root>' type=kotlin.ULong origin=null
x: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
$receiver: CONST Int type=kotlin.Int value=5
arg1: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
$receiver: CONST Long type=kotlin.Long value=5
then: CONST String type=kotlin.String value="Fail: testLong(5L)"
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun testLong (x: kotlin.ULong): kotlin.ULong declared in <root>' type=kotlin.ULong origin=null
x: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
$receiver: CONST Int type=kotlin.Int value=5
arg1: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
$receiver: CONST Long type=kotlin.Long value=5
then: CONST String type=kotlin.String value="Fail: testLong(x = 5L)"
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST String type=kotlin.String value="OK"
@@ -19,14 +19,22 @@ FILE fqName:kotlin.internal fileName:/annotation.kt
public open fun toString (): kotlin.String [fake_override] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FILE fqName:<root> fileName:/test.kt
FUN name:test visibility:public modality:FINAL <> (x:kotlin.UInt) returnType:kotlin.UInt
FUN name:testInt visibility:public modality:FINAL <> (x:kotlin.UInt) returnType:kotlin.UInt
VALUE_PARAMETER name:x index:0 type:kotlin.UInt
annotations:
ImplicitIntegerCoercion
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test (x: kotlin.UInt): kotlin.UInt declared in <root>'
RETURN type=kotlin.Nothing from='public final fun testInt (x: kotlin.UInt): kotlin.UInt declared in <root>'
TYPE_OP type=kotlin.UInt origin=CAST typeOperand=kotlin.UInt
GET_VAR 'x: kotlin.UInt declared in <root>.test' type=kotlin.UInt origin=null
GET_VAR 'x: kotlin.UInt declared in <root>.testInt' type=kotlin.UInt origin=null
FUN name:testLong visibility:public modality:FINAL <> (x:kotlin.ULong) returnType:kotlin.ULong
VALUE_PARAMETER name:x index:0 type:kotlin.ULong
annotations:
ImplicitIntegerCoercion
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testLong (x: kotlin.ULong): kotlin.ULong declared in <root>'
TYPE_OP type=kotlin.ULong origin=CAST typeOperand=kotlin.ULong
GET_VAR 'x: kotlin.ULong declared in <root>.testLong' type=kotlin.ULong origin=null
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
@@ -34,20 +42,35 @@ FILE fqName:<root> fileName:/test.kt
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun test (x: kotlin.UInt): kotlin.UInt declared in <root>' type=kotlin.UInt origin=null
x: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
arg0: CALL 'public final fun testInt (x: kotlin.UInt): kotlin.UInt declared in <root>' type=kotlin.UInt origin=null
x: CONST Int type=kotlin.UInt value=5
arg1: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
then: CONST String type=kotlin.String value="Fail: test(5)"
then: CONST String type=kotlin.String value="Fail: testInt(5)"
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun test (x: kotlin.UInt): kotlin.UInt declared in <root>' type=kotlin.UInt origin=null
x: CONST Int type=kotlin.Int value=5
arg0: CALL 'public final fun testInt (x: kotlin.UInt): kotlin.UInt declared in <root>' type=kotlin.UInt origin=null
x: CONST Int type=kotlin.UInt value=5
arg1: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
$receiver: CONST Int type=kotlin.Int value=5
then: CONST String type=kotlin.String value="Fail: test(x = 5)"
then: CONST String type=kotlin.String value="Fail: testInt(x = 5)"
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun testLong (x: kotlin.ULong): kotlin.ULong declared in <root>' type=kotlin.ULong origin=null
x: CONST Long type=kotlin.ULong value=5
arg1: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
$receiver: CONST Long type=kotlin.Long value=5
then: CONST String type=kotlin.String value="Fail: testLong(5L)"
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun testLong (x: kotlin.ULong): kotlin.ULong declared in <root>' type=kotlin.ULong origin=null
x: CONST Long type=kotlin.ULong value=5
arg1: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
$receiver: CONST Long type=kotlin.Long value=5
then: CONST String type=kotlin.String value="Fail: testLong(x = 5L)"
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST String type=kotlin.String value="OK"
@@ -0,0 +1,33 @@
// ISSUE: KT-57655
// !LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
// ALLOW_KOTLIN_PACKAGE
// WITH_STDLIB
// DUMP_IR
// IGNORE_BACKEND_K1: ANDROID
// STATUS:
// This line has been added because of the `AndroidRunner` test.
// This test runner appends a path-like prefix to all fully-qualified names,
// but the compiler logic for `ImplicitSignedToUnsignedIntegerConversion`
// relies on the ability to check exactly `kotlin.internal.ImplicitIntegerCoercion`.
// FILE: annotation.kt
package kotlin.internal
annotation class ImplicitIntegerCoercion
// FILE: test.kt
import kotlin.internal.ImplicitIntegerCoercion
fun testInt(@ImplicitIntegerCoercion x: UInt) = x as UInt
fun testLong(@ImplicitIntegerCoercion x: ULong) = x as ULong
fun box(): String = when {
testInt(5) != 5.toUInt() -> "Fail: testInt(5)"
testInt(x = 5) != 5.toUInt() -> "Fail: testInt(x = 5)"
testLong(5) != 5L.toULong() -> "Fail: testLong(5L)"
testLong(x = 5) != 5L.toULong() -> "Fail: testLong(x = 5L)"
else -> "OK"
}