FIR DFA: fix handling of equality operation
This commit is contained in:
committed by
teamcityserver
parent
0026560bd7
commit
e495c722c7
+40
-16
@@ -483,26 +483,50 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// propagating facts for (... == true) and (... == false)
|
// propagating facts for (... == true) and (... == false)
|
||||||
if (const.kind == ConstantValueKind.Boolean) {
|
when (const.kind) {
|
||||||
val constValue = const.value as Boolean
|
ConstantValueKind.Boolean -> {
|
||||||
val shouldInvert = isEq xor constValue
|
val constValue = const.value as Boolean
|
||||||
|
val shouldInvert = isEq xor constValue
|
||||||
|
|
||||||
logicSystem.translateVariableFromConditionInStatements(
|
logicSystem.translateVariableFromConditionInStatements(
|
||||||
flow,
|
flow,
|
||||||
operandVariable,
|
operandVariable,
|
||||||
expressionVariable,
|
expressionVariable,
|
||||||
shouldRemoveOriginalStatements = operandVariable.isSynthetic()
|
shouldRemoveOriginalStatements = operandVariable.isSynthetic()
|
||||||
) {
|
) {
|
||||||
when (it.condition.operation) {
|
when (it.condition.operation) {
|
||||||
Operation.EqNull, Operation.NotEqNull -> {
|
// Whatever the result is after comparing operandVariable with `true` or `false` cannot let you imply effects that apply
|
||||||
(expressionVariable eq isEq) implies (it.effect)
|
// when the operandVariable is null. Hence we return null here.
|
||||||
}
|
Operation.EqNull -> null
|
||||||
Operation.EqTrue, Operation.EqFalse -> {
|
Operation.NotEqNull -> {
|
||||||
if (shouldInvert) (it.condition.invert()) implies (it.effect)
|
(expressionVariable eq isEq) implies (it.effect)
|
||||||
else it
|
}
|
||||||
|
Operation.EqTrue, Operation.EqFalse -> {
|
||||||
|
if (shouldInvert) (it.condition.invert()) implies (it.effect)
|
||||||
|
else it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ConstantValueKind.Null -> {
|
||||||
|
logicSystem.translateVariableFromConditionInStatements(
|
||||||
|
flow,
|
||||||
|
operandVariable,
|
||||||
|
expressionVariable,
|
||||||
|
shouldRemoveOriginalStatements = operandVariable.isSynthetic()
|
||||||
|
) {
|
||||||
|
when (it.condition.operation) {
|
||||||
|
Operation.EqNull -> (expressionVariable eq isEq) implies (it.effect)
|
||||||
|
Operation.NotEqNull -> (expressionVariable eq !isEq) implies (it.effect)
|
||||||
|
// Whatever the result is after comparing operandVariable with `null` cannot let you imply effects that apply when the
|
||||||
|
// operandVariable is true or false.
|
||||||
|
Operation.EqTrue, Operation.EqFalse -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// Inconclusive if the user code compares with other constants.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
|||||||
newVariable: DataFlowVariable,
|
newVariable: DataFlowVariable,
|
||||||
shouldRemoveOriginalStatements: Boolean,
|
shouldRemoveOriginalStatements: Boolean,
|
||||||
filter: (Implication) -> Boolean = { true },
|
filter: (Implication) -> Boolean = { true },
|
||||||
transform: (Implication) -> Implication = { it },
|
transform: (Implication) -> Implication? = { it },
|
||||||
)
|
)
|
||||||
|
|
||||||
abstract fun approveStatementsInsideFlow(
|
abstract fun approveStatementsInsideFlow(
|
||||||
|
|||||||
+2
-2
@@ -297,11 +297,11 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
|
|||||||
newVariable: DataFlowVariable,
|
newVariable: DataFlowVariable,
|
||||||
shouldRemoveOriginalStatements: Boolean,
|
shouldRemoveOriginalStatements: Boolean,
|
||||||
filter: (Implication) -> Boolean,
|
filter: (Implication) -> Boolean,
|
||||||
transform: (Implication) -> Implication
|
transform: (Implication) -> Implication?
|
||||||
) {
|
) {
|
||||||
with(flow) {
|
with(flow) {
|
||||||
val statements = logicStatements[originalVariable]?.takeIf { it.isNotEmpty() } ?: return
|
val statements = logicStatements[originalVariable]?.takeIf { it.isNotEmpty() } ?: return
|
||||||
val newStatements = statements.filter(filter).map {
|
val newStatements = statements.filter(filter).mapNotNull {
|
||||||
val newStatement = OperationStatement(newVariable, it.condition.operation) implies it.effect
|
val newStatement = OperationStatement(newVariable, it.condition.operation) implies it.effect
|
||||||
transform(newStatement)
|
transform(newStatement)
|
||||||
}.toPersistentList()
|
}.toPersistentList()
|
||||||
|
|||||||
Vendored
+1
-1
@@ -116,7 +116,7 @@ fun case_5(value_1: Number?, value_2: String?) {
|
|||||||
fun case_6(value_1: Number, value_2: String?, value_3: Any?) {
|
fun case_6(value_1: Number, value_2: String?, value_3: Any?) {
|
||||||
when (value_3.case_6(value_1, value_2)) {
|
when (value_3.case_6(value_1, value_2)) {
|
||||||
true -> {
|
true -> {
|
||||||
println(value_3.equals(""))
|
println(value_3<!UNSAFE_CALL!>.<!>equals(""))
|
||||||
println(value_2<!UNSAFE_CALL!>.<!>length)
|
println(value_2<!UNSAFE_CALL!>.<!>length)
|
||||||
}
|
}
|
||||||
false -> {
|
false -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user