diff options
author | Nathan Ridge | 2015-02-17 07:18:31 +0000 |
---|---|---|
committer | Alena Laskavaia | 2015-02-19 00:30:08 +0000 |
commit | 43097ce04e05b0b8183d938b2d078211cfb535db (patch) | |
tree | 8c55e247b53d9c7cb7a8fda658d8db17f1f4849c /codan | |
parent | 3586267e6b0f97d0787aa143c0e6e2ab5b5e70be (diff) | |
download | org.eclipse.cdt-43097ce04e05b0b8183d938b2d078211cfb535db.tar.gz org.eclipse.cdt-43097ce04e05b0b8183d938b2d078211cfb535db.tar.xz org.eclipse.cdt-43097ce04e05b0b8183d938b2d078211cfb535db.zip |
Bug 455828 - Proper handling of 'switch' without explicit default
(including empty switch)
Change-Id: I3e20400f86c5e4273d8b0c62ed9ac3f429a84879
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Diffstat (limited to 'codan')
3 files changed, 58 insertions, 4 deletions
diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java index f158c645f18..5e61a07af6e 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java @@ -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); } diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java index 74c9ae466cb..baf1b3763b7 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java @@ -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); + } } diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java index a5b01093749..f1349c634b5 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java @@ -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()); } -}
\ No newline at end of file + + // int foo(int x) { // no warning + // switch (x) { + // } + // } + public void testEmptySwitch_455828() throws Exception { + loadCodeAndRunCpp(getAboveComment()); + checkErrorLine(1); + } +} |