1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 455828 - Proper handling of 'switch' without explicit default

(including empty switch)

Change-Id: I3e20400f86c5e4273d8b0c62ed9ac3f429a84879
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
Nathan Ridge 2015-02-17 02:18:31 -05:00 committed by Alena Laskavaia
parent 3586267e6b
commit 43097ce04e
3 changed files with 58 additions and 4 deletions

View file

@ -338,6 +338,7 @@ public class ControlFlowGraphBuilder {
IBasicBlock prev = switchNode;
IConnectorNode savedBreak = outerBreak;
outerBreak = mergeNode;
boolean encounteredDefault = false;
try {
for (IASTStatement statement : comp.getStatements()) {
if (statement instanceof IASTCaseStatement || statement instanceof IASTDefaultStatement) {
@ -346,6 +347,7 @@ public class ControlFlowGraphBuilder {
lbl = factory.createBranchNode(statement);
} else if (statement instanceof IASTDefaultStatement) {
lbl = factory.createBranchNode(IBranchNode.DEFAULT);
encounteredDefault = true;
}
if (!(prev instanceof IExitNode) && prev != switchNode) {
IConnectorNode here = factory.createConnectorNode();
@ -363,6 +365,16 @@ public class ControlFlowGraphBuilder {
} finally {
outerBreak = savedBreak;
}
// If the switch didn't have an explicit 'default' case, we still have to
// add an edge for the situation where no case was matched.
if (!encounteredDefault) {
if (!(prev instanceof IExitNode) && prev != switchNode) {
addJump(prev, mergeNode);
}
IBranchNode defaultBranch = factory.createBranchNode(IBranchNode.DEFAULT);
addOutgoing(switchNode, defaultBranch);
prev = defaultBranch;
}
addJump(prev, mergeNode);
}

View file

@ -638,4 +638,27 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
IJumpNode case1Jump = (IJumpNode) case1Branch.getOutgoing();
assertEquals(swittch.getMergeNode(), case1Jump.getJumpNode());
}
// int main(int a) {
// switch (a) {
// }
// }
public void test_empty_switch() {
buildAndCheck(getAboveComment());
// Decision node should be optimized away entirely
assertFalse(graph.getStartNode() instanceof IDecisionNode);
}
// int main(int a) {
// switch (a) {
// case 1: {
// break;
// }
// }
// }
public void test_switch_no_explicit_default() {
buildAndCheck(getAboveComment());
IDecisionNode swittch = (IDecisionNode) graph.getStartNode().getOutgoing();
assertTrue(swittch.getOutgoingSize() == 2);
}
}

View file

@ -241,10 +241,20 @@ public class ReturnCheckerTest extends CheckerTestCase {
// {
// switch (g()) {
// case 1: return 1;
// case 2:
// return 0;
// case 2: return 0;
// }
public void testBranchesSwitch_Bug343767() {
public void testBranchesSwitch_Bug343767a() {
loadCodeAndRunCpp(getAboveComment());
checkErrorLine(1);
}
// int f()
// {
// switch (g()) {
// case 1: return 1;
// case 2: return 0;
// default: return -1;
// }
public void testBranchesSwitch_Bug343767b() {
loadCodeAndRunCpp(getAboveComment());
checkNoErrors();
}
@ -429,4 +439,13 @@ public class ReturnCheckerTest extends CheckerTestCase {
// Just check that codan runs without any exceptions being thrown.
loadCodeAndRunCpp(getAboveComment());
}
}
// int foo(int x) { // no warning
// switch (x) {
// }
// }
public void testEmptySwitch_455828() throws Exception {
loadCodeAndRunCpp(getAboveComment());
checkErrorLine(1);
}
}