[FIR] Fix various corner cases in DFA
This commit is contained in:
+27
-24
@@ -184,7 +184,9 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
flow.addTypeStatement(operandVariable typeEq any)
|
||||
}
|
||||
if (isNotNullCheck) {
|
||||
flow.addImplication((expressionVariable eq true) implies (operandVariable typeEq any)) }
|
||||
flow.addImplication((expressionVariable eq true) implies (operandVariable typeEq any))
|
||||
flow.addImplication((expressionVariable eq true) implies (operandVariable notEq null))
|
||||
}
|
||||
|
||||
} else {
|
||||
if (isNotNullCheck) {
|
||||
@@ -196,14 +198,13 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
FirOperation.AS -> {
|
||||
if (operandVariable.isReal()) {
|
||||
flow.addTypeStatement(operandVariable typeEq type)
|
||||
} else {
|
||||
logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
operandVariable notEq null,
|
||||
shouldRemoveSynthetics = true,
|
||||
shouldForkFlow = false
|
||||
)
|
||||
}
|
||||
logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
operandVariable notEq null,
|
||||
shouldRemoveSynthetics = true,
|
||||
shouldForkFlow = false
|
||||
)
|
||||
}
|
||||
|
||||
FirOperation.SAFE_AS -> {
|
||||
@@ -329,6 +330,12 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
val argument = checkNotNullCall.argument
|
||||
val operandVariable = variableStorage.getOrCreateRealVariable(argument.symbol, argument) ?: return
|
||||
node.flow.addTypeStatement(operandVariable typeEq any)
|
||||
logicSystem.approveStatementsInsideFlow(
|
||||
node.flow,
|
||||
operandVariable notEq null,
|
||||
shouldRemoveSynthetics = true,
|
||||
shouldForkFlow = false
|
||||
)
|
||||
}
|
||||
|
||||
// ----------------------------------- When -----------------------------------
|
||||
@@ -511,22 +518,19 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
?.withNullability(ConeNullability.NOT_NULL)
|
||||
?: return@let
|
||||
|
||||
when (val variable = variableStorage.getOrCreateVariable(receiver)) {
|
||||
is RealVariable -> {
|
||||
if (shouldFork) {
|
||||
flow = logicSystem.forkFlow(flow)
|
||||
}
|
||||
flow.addTypeStatement(variable typeEq type)
|
||||
}
|
||||
is SyntheticVariable -> {
|
||||
flow = logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
variable notEq null,
|
||||
shouldFork,
|
||||
shouldRemoveSynthetics = true
|
||||
)
|
||||
val variable = variableStorage.getOrCreateVariable(receiver)
|
||||
if (variable is RealVariable) {
|
||||
if (shouldFork) {
|
||||
flow = logicSystem.forkFlow(flow)
|
||||
}
|
||||
flow.addTypeStatement(variable typeEq type)
|
||||
}
|
||||
flow = logicSystem.approveStatementsInsideFlow(
|
||||
flow,
|
||||
variable notEq null,
|
||||
shouldFork,
|
||||
shouldRemoveSynthetics = true
|
||||
)
|
||||
}
|
||||
|
||||
node.flow = flow
|
||||
@@ -654,9 +658,8 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
variableStorage.getOrCreateRealVariable(initializer.symbol, initializer)?.let { initializerVariable ->
|
||||
if (initializerVariable.isStable) {
|
||||
variableStorage.attachSymbolToVariable(variable.symbol, initializerVariable)
|
||||
} else {
|
||||
node.flow.addImplication((propertyVariable notEq null) implies (initializerVariable notEq null))
|
||||
}
|
||||
node.flow.addImplication((propertyVariable notEq null) implies (initializerVariable notEq null))
|
||||
}
|
||||
|
||||
if (!isVariableDeclaration) {
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ fun kt4565_1(a: SomeClass?) {
|
||||
a.data.hashCode()
|
||||
}
|
||||
if (a?.data is String) {
|
||||
a.<!INAPPLICABLE_CANDIDATE!>data<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
a.data.length
|
||||
data.length
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -58,7 +58,8 @@ FILE fqName:<root> fileName:/kt30020.kt
|
||||
$receiver: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
|
||||
<T0>: kotlin.collections.MutableList<kotlin.Any>
|
||||
arg0: CALL 'public abstract fun f (): kotlin.collections.MutableList<kotlin.Any> declared in <root>.X' type=kotlin.collections.MutableList<kotlin.Any>? origin=null
|
||||
$this: GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
|
||||
$this: TYPE_OP type=<root>.X origin=IMPLICIT_CAST typeOperand=<root>.X
|
||||
GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
|
||||
element: CONST Int type=kotlin.Int value=6
|
||||
FUN name:testExtensionReceiver visibility:public modality:FINAL <> ($receiver:kotlin.collections.MutableList<kotlin.Any>) returnType:kotlin.Unit
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableList<kotlin.Any>
|
||||
|
||||
Reference in New Issue
Block a user