Bug 455828 - Proper handling of 'break' inside compound statement in a

case of a switch

Change-Id: I73329a8769bc20a4fc4e017faad627e03adce9d9
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
Nathan Ridge 2015-02-17 01:51:57 -05:00 committed by Alena Laskavaia
parent 340b507e38
commit 3586267e6b
2 changed files with 45 additions and 22 deletions

View file

@ -336,30 +336,32 @@ public class ControlFlowGraphBuilder {
return; // bad
IASTCompoundStatement comp = (IASTCompoundStatement) body;
IBasicBlock prev = switchNode;
for (IASTStatement statement : comp.getStatements()) {
if (statement instanceof IASTCaseStatement || statement instanceof IASTDefaultStatement) {
IBranchNode lbl = null;
if (statement instanceof IASTCaseStatement) {
lbl = factory.createBranchNode(statement);
} else if (statement instanceof IASTDefaultStatement) {
lbl = factory.createBranchNode(IBranchNode.DEFAULT);
IConnectorNode savedBreak = outerBreak;
outerBreak = mergeNode;
try {
for (IASTStatement statement : comp.getStatements()) {
if (statement instanceof IASTCaseStatement || statement instanceof IASTDefaultStatement) {
IBranchNode lbl = null;
if (statement instanceof IASTCaseStatement) {
lbl = factory.createBranchNode(statement);
} else if (statement instanceof IASTDefaultStatement) {
lbl = factory.createBranchNode(IBranchNode.DEFAULT);
}
if (!(prev instanceof IExitNode) && prev != switchNode) {
IConnectorNode here = factory.createConnectorNode();
addJump(prev, here);
addOutgoing(lbl, here);
prev = here;
} else {
prev = lbl;
}
addOutgoing(switchNode, lbl);
continue;
}
if (!(prev instanceof IExitNode) && prev != switchNode) {
IConnectorNode here = factory.createConnectorNode();
addJump(prev, here);
addOutgoing(lbl, here);
prev = here;
} else {
prev = lbl;
}
addOutgoing(switchNode, lbl);
continue;
prev = createSubGraph(prev, statement);
}
if (statement instanceof IASTBreakStatement) {
prev = addJump(prev, mergeNode);
continue;
}
prev = createSubGraph(prev, statement);
} finally {
outerBreak = savedBreak;
}
addJump(prev, mergeNode);
}

View file

@ -617,4 +617,25 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
IBranchNode trueBranch = (IBranchNode) graph.getUnconnectedNodeIterator().next();
assertEquals("return 1;", data(trueBranch.getOutgoing()));
}
// int main(int a) {
// switch (a) {
// case 1: {
// break;
// }
// case 2: {
// break;
// }
// }
// }
public void test_switch_break_in_compound_statement() {
// Test that the target node of the jump for the 'break' in a case
// is the connector node at the end of the switch, not the connector
// node for the next case.
buildAndCheck(getAboveComment());
IDecisionNode swittch = (IDecisionNode) graph.getStartNode().getOutgoing();
IPlainNode case1Branch = (IPlainNode) swittch.getOutgoingNodes()[0];
IJumpNode case1Jump = (IJumpNode) case1Branch.getOutgoing();
assertEquals(swittch.getMergeNode(), case1Jump.getJumpNode());
}
}