DfaMemoryStateImpl: avoid exponential blow up of canonicalize calls

GitOrigin-RevId: 61c65025d6f6626d500a0174a96d129dc124147e
This commit is contained in:
Tagir Valeev
2019-06-03 13:11:37 +03:00
committed by intellij-monorepo-bot
parent 6b6794585a
commit 203a70e40f
3 changed files with 71 additions and 2 deletions
@@ -1419,8 +1419,16 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
private DfaVariableValue canonicalize(DfaVariableValue var) {
DfaVariableValue qualifier = var.getQualifier();
if (qualifier != null) {
EqClass eqClass = getEqClass(qualifier);
return var.withQualifier(eqClass == null ? canonicalize(qualifier) : Objects.requireNonNull(eqClass.getCanonicalVariable()));
Integer index = myIdToEqClassesIndices.get(qualifier.getID());
if (index == null) {
qualifier = canonicalize(qualifier);
index = myIdToEqClassesIndices.get(qualifier.getID());
if (index == null) {
return var.withQualifier(qualifier);
}
}
return var.withQualifier(Objects.requireNonNull(myEqClasses.get(index).getCanonicalVariable()));
}
return var;
}
@@ -0,0 +1,60 @@
import java.util.Optional;
class App {
public static void main(String[] args) {
Optional.of("foo")
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x))
.map(x -> Optional.of(x));
}
}
@@ -246,4 +246,5 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
}
public void testLambdaWritesArrayInTry() { doTest(); }
public void testManyNestedOptionals() { doTest(); }
}