[FIR] KT-56723: Ensure safe access over non-expressions is always Unit

^KT-56723 Fixed
This commit is contained in:
Nikolay Lunyak
2023-02-17 18:04:51 +02:00
committed by Space Team
parent a8370ea994
commit be5850112a
22 changed files with 414 additions and 18 deletions
+91
View File
@@ -0,0 +1,91 @@
import kotlin.reflect.KProperty
fun foo(f: () -> Unit) {
f()
}
class Wrapper(var s: String)
fun bar(w: Wrapper?) {
// K1: type is () -> Unit, K2: type is () -> Unit?
val lambda = {
w?.s = "X"
}
// K1: Ok, K2: ARGUMENT_TYPE_MISMATCH
foo(lambda)
}
class Wrapper2(val w: Wrapper?)
fun baz(w2: Wrapper2?) {
val lambda = {
w2?.w?.s = "X"
}
foo(lambda)
}
object Indexible {
operator fun get(index: Int) = "$index"
operator fun set(index: Int, value: String) {}
}
class IndexibleRef(val ind: Indexible)
class IndexibleRefRef(val ref: IndexibleRef?)
fun ban(refRef: IndexibleRefRef?, ref: IndexibleRef?) {
val lambda = {
ref?.ind[1] = "X"
}
foo(lambda)
val lambda2 = {
refRef?.ref?.ind[1] = "X"
}
foo(lambda2)
val lambda3 = {
ref?.ind?.set(1, "X")
}
foo(<!ARGUMENT_TYPE_MISMATCH!>lambda3<!>)
val lambda4 = {
refRef?.ref?.ind?.set(1, "X")
}
foo(<!ARGUMENT_TYPE_MISMATCH!>lambda4<!>)
}
object PlusAssignable {
operator fun plusAssign(index: Int) {}
}
object Indexible2 {
operator fun get(index: Int) = PlusAssignable
operator fun set(index: Int, value: String) {}
}
class Indexible2Ref(val ind: Indexible2)
fun bam(ref: Indexible2Ref?) {
val lambda = {
ref?.ind[1] += 1
}
foo(lambda)
val lambd2 = {
ref?.ind?.get(1)?.plusAssign(1)
}
foo(lambda)
}
class DelegatedHolder {
var delegated by object {
operator fun getValue(thisRef: Any?, desc: KProperty<*>) = "test"
operator fun setValue(thisRef: Any?, desc: KProperty<*>, value: String) {}
}
}
fun bap(holder: DelegatedHolder?) {
val lambda = {
holder?.delegated = "Y"
}
foo(lambda)
}
+91
View File
@@ -0,0 +1,91 @@
import kotlin.reflect.KProperty
fun foo(f: () -> Unit) {
f()
}
class Wrapper(var s: String)
fun bar(w: Wrapper?) {
// K1: type is () -> Unit, K2: type is () -> Unit?
val lambda = {
w?.s = "X"
}
// K1: Ok, K2: ARGUMENT_TYPE_MISMATCH
foo(lambda)
}
class Wrapper2(val w: Wrapper?)
fun baz(w2: Wrapper2?) {
val lambda = {
w2?.w?.s = "X"
}
foo(lambda)
}
object Indexible {
operator fun get(index: Int) = "$index"
operator fun set(index: Int, value: String) {}
}
class IndexibleRef(val ind: Indexible)
class IndexibleRefRef(val ref: IndexibleRef?)
fun ban(refRef: IndexibleRefRef?, ref: IndexibleRef?) {
val lambda = {
<!UNSAFE_CALL!>ref?.ind[1]<!> = "X"
}
foo(lambda)
val lambda2 = {
<!UNSAFE_CALL!>refRef?.ref?.ind[1]<!> = "X"
}
foo(lambda2)
val lambda3 = {
ref?.ind?.set(1, "X")
}
foo(<!UNSUPPORTED_FEATURE!>lambda3<!>)
val lambda4 = {
refRef?.ref?.ind?.set(1, "X")
}
foo(<!UNSUPPORTED_FEATURE!>lambda4<!>)
}
object PlusAssignable {
operator fun plusAssign(index: Int) {}
}
object Indexible2 {
operator fun get(index: Int) = PlusAssignable
operator fun set(index: Int, value: String) {}
}
class Indexible2Ref(val ind: Indexible2)
fun bam(ref: Indexible2Ref?) {
val lambda = {
<!UNSAFE_CALL!>ref?.ind[1]<!> += 1
}
foo(lambda)
val lambd2 = {
ref?.ind?.get(1)?.plusAssign(1)
}
foo(lambda)
}
class DelegatedHolder {
var delegated by object {
operator fun getValue(thisRef: Any?, desc: KProperty<*>) = "test"
operator fun setValue(thisRef: Any?, desc: KProperty<*>, value: String) {}
}
}
fun bap(holder: DelegatedHolder?) {
val lambda = {
holder?.delegated = "Y"
}
foo(lambda)
}
+83
View File
@@ -0,0 +1,83 @@
package
public fun bam(/*0*/ ref: Indexible2Ref?): kotlin.Unit
public fun ban(/*0*/ refRef: IndexibleRefRef?, /*1*/ ref: IndexibleRef?): kotlin.Unit
public fun bap(/*0*/ holder: DelegatedHolder?): kotlin.Unit
public fun bar(/*0*/ w: Wrapper?): kotlin.Unit
public fun baz(/*0*/ w2: Wrapper2?): kotlin.Unit
public fun foo(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public final class DelegatedHolder {
public constructor DelegatedHolder()
public final var delegated: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Indexible {
private constructor Indexible()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final operator fun get(/*0*/ index: kotlin.Int): kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.String): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Indexible2 {
private constructor Indexible2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final operator fun get(/*0*/ index: kotlin.Int): PlusAssignable
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun set(/*0*/ index: kotlin.Int, /*1*/ value: kotlin.String): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Indexible2Ref {
public constructor Indexible2Ref(/*0*/ ind: Indexible2)
public final val ind: Indexible2
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class IndexibleRef {
public constructor IndexibleRef(/*0*/ ind: Indexible)
public final val ind: Indexible
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class IndexibleRefRef {
public constructor IndexibleRefRef(/*0*/ ref: IndexibleRef?)
public final val ref: IndexibleRef?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object PlusAssignable {
private constructor PlusAssignable()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun plusAssign(/*0*/ index: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Wrapper {
public constructor Wrapper(/*0*/ s: kotlin.String)
public final var s: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Wrapper2 {
public constructor Wrapper2(/*0*/ w: Wrapper?)
public final val w: Wrapper?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}