FIR DFA: don't assume != true/false => == false/true

This also fixes some returnsNotNull contracts because the old code added
an implication that `== true` => `!= null` then promptly removed any
statement that this could've affected if the argument was a synthetic
variable.

^KT-26612 tag fixed-in-k2
This commit is contained in:
pyos
2022-11-10 17:42:08 +01:00
committed by teamcity
parent 98f52f13ef
commit 5b08c300f4
9 changed files with 47 additions and 106 deletions
@@ -19,31 +19,22 @@ class MutableTypeStatement(
fun copy(): MutableTypeStatement = MutableTypeStatement(variable, LinkedHashSet(exactType))
}
fun Implication.invertCondition(): Implication = Implication(condition.invert(), effect)
// --------------------------------------- Aliases ---------------------------------------
typealias TypeStatements = Map<RealVariable, TypeStatement>
// --------------------------------------- DSL ---------------------------------------
infix fun DataFlowVariable.eq(constant: Boolean?): OperationStatement {
val condition = when (constant) {
true -> Operation.EqTrue
false -> Operation.EqFalse
null -> Operation.EqNull
}
return OperationStatement(this, condition)
}
infix fun DataFlowVariable.eq(constant: Boolean): OperationStatement =
OperationStatement(this, if (constant) Operation.EqTrue else Operation.EqFalse)
infix fun DataFlowVariable.notEq(constant: Boolean?): OperationStatement {
val condition = when (constant) {
true -> Operation.EqFalse
false -> Operation.EqTrue
null -> Operation.NotEqNull
}
return OperationStatement(this, condition)
}
@Suppress("UNUSED_PARAMETER")
infix fun DataFlowVariable.eq(constant: Nothing?): OperationStatement =
OperationStatement(this, Operation.EqNull)
@Suppress("UNUSED_PARAMETER")
infix fun DataFlowVariable.notEq(constant: Nothing?): OperationStatement =
OperationStatement(this, Operation.NotEqNull)
infix fun OperationStatement.implies(effect: Statement): Implication = Implication(this, effect)
@@ -19,10 +19,6 @@ sealed class Statement {
* d == False
*/
data class OperationStatement(override val variable: DataFlowVariable, val operation: Operation) : Statement() {
fun invert(): OperationStatement {
return OperationStatement(variable, operation.invert())
}
override fun toString(): String {
return "$variable $operation"
}
@@ -55,13 +51,6 @@ class Implication(
enum class Operation {
EqTrue, EqFalse, EqNull, NotEqNull;
fun invert(): Operation = when (this) {
EqTrue -> EqFalse
EqFalse -> EqTrue
EqNull -> NotEqNull
NotEqNull -> EqNull
}
fun valueIfKnown(given: Operation): Boolean? = when (this) {
EqTrue, EqFalse -> if (given == NotEqNull) null else given == this
EqNull -> given == EqNull