DFA: better union of nullability states

Union in merge procedure differs from normal union: in normal union it's ok to (NULLABLE | NOT_NULL) -> NULLABLE,
but in merge we should produce FLUSHED
This commit is contained in:
Tagir Valeev
2019-03-14 11:10:38 +07:00
parent a96fd977e1
commit 6c51666a85
2 changed files with 16 additions and 4 deletions
@@ -73,10 +73,14 @@ public abstract class DfaFactType<T> extends Key<T> {
if (left == right) {
return left;
}
if (left == DfaNullability.NULL || right == DfaNullability.NULL) {
return DfaNullability.UNKNOWN;
if (left == DfaNullability.NULL || right == DfaNullability.NULL ||
left == DfaNullability.NULLABLE || right == DfaNullability.NULLABLE) {
return DfaNullability.NULLABLE;
}
return DfaNullability.FLUSHED;
if (left == DfaNullability.FLUSHED || right == DfaNullability.FLUSHED) {
return DfaNullability.FLUSHED;
}
return DfaNullability.UNKNOWN;
}
@Nullable
@@ -1651,7 +1651,15 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
for (DfaVariableValue var : vars) {
DfaVariableState state = getVariableState(var);
DfaVariableState otherState = other.getVariableState(var);
setVariableState(var, state.withFacts(state.myFactMap.unite(otherState.myFactMap)));
DfaFactMap result = state.myFactMap.unite(otherState.myFactMap);
Nullability nullability = state.getNullability();
Nullability otherNullability = otherState.getNullability();
if (nullability != otherNullability && (nullability == Nullability.NULLABLE || otherNullability == Nullability.NULLABLE)) {
// When merging nullable with something we cannot warn about nullability violation anymore
// because we lose the information about coherent state, thus noise warnings could be produced
result = result.with(DfaFactType.NULLABILITY, DfaNullability.FLUSHED);
}
setVariableState(var, state.withFacts(result));
}
}