Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/codan
diff options
context:
space:
mode:
authorNathan Ridge2015-02-17 07:18:31 +0000
committerAlena Laskavaia2015-02-19 00:30:08 +0000
commit43097ce04e05b0b8183d938b2d078211cfb535db (patch)
tree8c55e247b53d9c7cb7a8fda658d8db17f1f4849c /codan
parent3586267e6b0f97d0787aa143c0e6e2ab5b5e70be (diff)
downloadorg.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')
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java12
-rw-r--r--codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java23
-rw-r--r--codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java27
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);
+ }
+}

Back to the top