FIR DFA: check for reassignments of LHS when handling ?..
`x?.y != null` does not imply that `x != null` if e.g. an argument to `y` has reassigned `x` in the meantime. The same is true for `x == y` and `functionWithContract(x, y)`, but those are somewhat harder to implement since there is no easy way to find the last node of a certain argument. ^KT-55096
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.dfa
|
||||
|
||||
abstract class Flow {
|
||||
abstract val approvedTypeStatements: TypeStatements
|
||||
abstract val knownVariables: Set<RealVariable>
|
||||
abstract fun unwrapVariable(variable: RealVariable): RealVariable
|
||||
abstract fun getTypeStatement(variable: RealVariable): TypeStatement?
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
||||
abstract fun recordNewAssignment(flow: FLOW, variable: RealVariable, index: Int)
|
||||
abstract fun removeAllAboutVariable(flow: FLOW, variable: RealVariable)
|
||||
abstract fun copyAllInformation(from: FLOW, to: FLOW)
|
||||
abstract fun isSameValueIn(a: FLOW, b: FLOW, variable: RealVariable): Boolean
|
||||
|
||||
abstract fun translateVariableFromConditionInStatements(
|
||||
flow: FLOW,
|
||||
|
||||
+8
-3
@@ -22,7 +22,7 @@ typealias PersistentImplications = PersistentMap<DataFlowVariable, PersistentLis
|
||||
|
||||
class PersistentFlow : Flow {
|
||||
val previousFlow: PersistentFlow?
|
||||
override var approvedTypeStatements: PersistentApprovedTypeStatements
|
||||
var approvedTypeStatements: PersistentApprovedTypeStatements
|
||||
var logicStatements: PersistentImplications
|
||||
val level: Int
|
||||
|
||||
@@ -60,6 +60,9 @@ class PersistentFlow : Flow {
|
||||
assignmentIndex = persistentMapOf()
|
||||
}
|
||||
|
||||
override val knownVariables: Set<RealVariable>
|
||||
get() = approvedTypeStatements.keys + directAliasMap.keys
|
||||
|
||||
override fun unwrapVariable(variable: RealVariable): RealVariable =
|
||||
directAliasMap[variable] ?: variable
|
||||
|
||||
@@ -126,8 +129,7 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
}
|
||||
|
||||
val approvedTypeStatements = result.approvedTypeStatements.builder()
|
||||
val allVariablesWithStatements = flows.flatMapTo(mutableSetOf()) { it.approvedTypeStatements.keys + it.directAliasMap.keys }
|
||||
allVariablesWithStatements.forEach computeStatement@{ variable ->
|
||||
flows.flatMapTo(mutableSetOf()) { it.knownVariables }.forEach computeStatement@{ variable ->
|
||||
val statement = if (variable in result.directAliasMap) {
|
||||
return@computeStatement // statements about alias == statements about aliased variable
|
||||
} else if (!allExecute) {
|
||||
@@ -321,6 +323,9 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
||||
removeAllAboutVariable(flow, variable)
|
||||
flow.assignmentIndex = flow.assignmentIndex.put(variable, index)
|
||||
}
|
||||
|
||||
override fun isSameValueIn(a: PersistentFlow, b: PersistentFlow, variable: RealVariable): Boolean =
|
||||
a.assignmentIndex[variable] == b.assignmentIndex[variable]
|
||||
}
|
||||
|
||||
private fun lowestCommonFlow(left: PersistentFlow, right: PersistentFlow): PersistentFlow {
|
||||
|
||||
Reference in New Issue
Block a user