Skip to content

Commit af64a20

Browse files
committed
Handle multiple case expressions
As a side effect, fall throughs now go to the next block, not the next case expression
1 parent 30b0f04 commit af64a20

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

spoon-control-flow/src/main/java/fr/inria/controlflow/ControlFlowBuilder.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
import spoon.reflect.visitor.CtAbstractVisitor;
115115

116116
import java.lang.annotation.Annotation;
117+
import java.util.ArrayList;
117118
import java.util.HashMap;
118119
import java.util.List;
119120
import java.util.Stack;
@@ -390,7 +391,12 @@ public <T> void visitCtBinaryOperator(CtBinaryOperator<T> operator) {
390391

391392
}
392393

393-
private <R> void travelStatementList(List<CtStatement> statements) {
394+
/**
395+
* Add a list of statements as a block to the current CFG.
396+
* @param statements The list of statements
397+
* @return The start node of the block
398+
*/
399+
private ControlFlowNode travelStatementList(List<CtStatement> statements) {
394400
ControlFlowNode begin = new ControlFlowNode(null, result, BranchKind.BLOCK_BEGIN);
395401
tryAddEdge(lastNode, begin);
396402
lastNode = begin;
@@ -402,6 +408,7 @@ private <R> void travelStatementList(List<CtStatement> statements) {
402408
ControlFlowNode end = new ControlFlowNode(null, result, BranchKind.BLOCK_END);
403409
tryAddEdge(lastNode, end);
404410
lastNode = end;
411+
return begin;
405412
}
406413

407414
@Override
@@ -774,14 +781,34 @@ public <S> void visitCtSwitch(CtSwitch<S> switchStatement) {
774781

775782
//Visit Case
776783
registerStatementLabel(caseStatement);
777-
ControlFlowNode cn = new ControlFlowNode(caseStatement.getCaseExpression(), result, BranchKind.STATEMENT);
778-
hasDefaultCase |= caseStatement.getCaseExpressions().isEmpty();
779-
tryAddEdge(lastNode, cn);
780-
if (lastNode != switchNode) {
781-
tryAddEdge(switchNode, cn);
784+
var caseExpressions = caseStatement.getCaseExpressions();
785+
ArrayList<ControlFlowNode> caseExpressionNodes = new ArrayList<>();
786+
for (CtExpression<?> expression: caseExpressions) {
787+
ControlFlowNode caseNode = new ControlFlowNode(expression, result, BranchKind.STATEMENT);
788+
caseExpressionNodes.add(caseNode);
789+
tryAddEdge(switchNode, caseNode);
790+
}
791+
792+
if (caseExpressionNodes.isEmpty()) {
793+
hasDefaultCase = true;
794+
ControlFlowNode defaultNode = new ControlFlowNode(null, result, BranchKind.STATEMENT);
795+
caseExpressionNodes.add(defaultNode);
796+
tryAddEdge(switchNode, defaultNode);
797+
}
798+
799+
ControlFlowNode fallThroughEnd = null;
800+
if(lastNode != switchNode) {
801+
fallThroughEnd = lastNode;
782802
}
783-
lastNode = cn;
784-
travelStatementList(caseStatement.getStatements());
803+
lastNode = null;
804+
805+
ControlFlowNode blockStart = travelStatementList(caseStatement.getStatements());
806+
tryAddEdge(fallThroughEnd, blockStart);
807+
808+
for (ControlFlowNode expressionNode : caseExpressionNodes) {
809+
tryAddEdge(expressionNode, blockStart);
810+
}
811+
785812
if (lastNode.getStatement() instanceof CtBreak) {
786813
lastNode = switchNode;
787814
}

0 commit comments

Comments
 (0)