Skip to content

Commit d5306ab

Browse files
authored
Fix stats desync issue and add validation checks (#603)
1 parent 4bd6945 commit d5306ab

2 files changed

Lines changed: 22 additions & 4 deletions

File tree

src/org/jetbrains/java/decompiler/modules/decompiler/ValidationHelper.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,36 @@ public static void validateStatement(RootStatement statement) {
3838
while (!stack.isEmpty()) {
3939
Statement stat = stack.pop();
4040

41-
statements.putWithKey(stat, stat.id);
42-
43-
stack.addAll(stat.getStats());
41+
if (statements.containsKey(stat.id)) {
42+
if (statements.getWithKey(stat.id) != stat){
43+
throw new IllegalStateException("2 stats with the same id: " + stat + " vs " + statements.getWithKey(stat.id));
44+
}
45+
// The else case means multiple parent. A later check will produce better error than we could do here.
46+
} else {
47+
statements.putWithKey(stat, stat.id);
48+
stack.addAll(stat.getStats());
49+
}
4450
}
4551

4652
for (Statement stat : statements) {
4753
for (StatEdge edge : stat.getAllSuccessorEdges()) {
54+
if (edge.getSource() != stat) {
55+
throw new IllegalStateException("Stat " + stat + " has successor edge for which it isn't the source: " + edge);
56+
}
4857
validateEdgeContext(statements, stat, edge);
4958
}
5059

5160
for (StatEdge edge : stat.getAllPredecessorEdges()) {
61+
if (edge.getDestination() != stat) {
62+
throw new IllegalStateException("Stat " + stat + " has predecessor edge for which it isn't the destination: " + edge);
63+
}
5264
validateEdgeContext(statements, stat, edge);
5365
}
5466

5567
for (StatEdge edge : stat.getLabelEdges()) {
68+
if (edge.closure != stat) {
69+
throw new IllegalStateException("Stat " + stat + " has a labelled edge for which it isn't the closure: " + edge);
70+
}
5671
validateEdgeContext(statements, stat, edge);
5772
}
5873

@@ -74,6 +89,9 @@ public static void validateStatement(RootStatement statement) {
7489
if (statStat.getParent() != stat) {
7590
throw new IllegalStateException("Statement parent is not set correctly [" + statStat + "]: Expected " + stat + " but was " + statStat.getParent());
7691
}
92+
if (!stat.getStats().containsKey(statStat.id)){
93+
throw new IllegalStateException("Statement " + stat + " contains non stat without id lookup: " + statStat);
94+
}
7795
}
7896

7997
validateSingleStatement(stat);

src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ public void addCase(int index, List<Exprent> values, Statement stat) {
578578

579579
private void addCaseInternal(int index, List<@Nullable Exprent> values, Statement stat) {
580580
// Basichead is always the first stat
581-
this.getStats().add(1 + index, stat);
581+
this.getStats().addWithKeyAndIndex(1 + index, stat, stat.id);
582582
this.getCaseStatements().add(index, stat);
583583
this.getCaseValues().add(index, values);
584584

0 commit comments

Comments
 (0)