[FIR] Fix DFA behaviour for a case with == (!=) true / false

This commit is contained in:
Mikhail Glukhikh
2020-02-06 15:27:38 +03:00
parent 36ba8bf6a9
commit 2fb508aa1b
5 changed files with 73 additions and 4 deletions
@@ -268,8 +268,15 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
expressionVariable,
shouldRemoveOriginalStatements = operandVariable.isSynthetic()
) {
if (shouldInvert) (it.condition.invert()) implies (it.effect)
else it
when (it.condition.operation) {
Operation.EqNull, Operation.NotEqNull -> {
(expressionVariable eq isEq) implies (it.effect)
}
Operation.EqTrue, Operation.EqFalse -> {
if (shouldInvert) (it.condition.invert()) implies (it.effect)
else it
}
}
}
}
}
@@ -32,7 +32,7 @@ fun <D : Descriptor> test(call: Call<D>, resolvedCall: ResolvedCall<D>) {
val resolvedDescriptor = resolvedCall.candidateDescriptor
if (resolvedDescriptor?.correct() != true) return
resolvedDescriptor.<!INAPPLICABLE_CANDIDATE!>foo<!>()
resolvedDescriptor.foo()
}
fun otherTest(call: Call<*>, resolvedCall: ResolvedCall<*>) {
@@ -21,7 +21,7 @@ FILE: test.kt
}
}
R|<local>/resolvedDescriptor|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
R|<local>/resolvedDescriptor|.R|/foo|()
}
public final fun otherTest(call: R|Call<*>|, resolvedCall: R|ResolvedCall<*>|): R|kotlin/Unit| {
R|<local>/call|.R|FakeOverride</Call.resultingDescriptor: R|Descriptor|>|.R|/name|
@@ -12,10 +12,36 @@ fun foo(a: Any?) {
fun bar(s: String?) {
if (s?.isNotEmpty() == true) {
s.length
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
fun bar_2(s: String?) {
if (s?.isNotEmpty() == false) {
s.length
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
fun bar_3(s: String?) {
if (s?.isNotEmpty() != true) {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
} else {
s.length
}
}
fun bar_4(s: String?) {
if (s?.isNotEmpty() != false) {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
} else {
s.length
}
}
fun baz(s: String?) {
when {
!s.isNullOrEmpty() -> s.<!INAPPLICABLE_CANDIDATE!>length<!>
@@ -25,10 +25,46 @@ FILE: complexSmartCasts.kt
public final fun bar(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(true)) -> {
R|<local>/s|.R|kotlin/String.length|
}
else -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun bar_2(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(false)) -> {
R|<local>/s|.R|kotlin/String.length|
}
else -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun bar_3(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
!=(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(true)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
public final fun bar_4(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
!=(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(false)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
public final fun baz(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {