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:
parent
3586267e6b
commit
43097ce04e
3 changed files with 58 additions and 4 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue