Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/codan
diff options
context:
space:
mode:
Diffstat (limited to 'codan')
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java11
-rw-r--r--codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java14
2 files changed, 25 insertions, 0 deletions
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java
index 2c528ab5153..7d3a6beb854 100644
--- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java
+++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java
@@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
@@ -90,6 +91,9 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
IASTStatement next = null;
if (i < statements.length - 1)
next = statements[i + 1];
+ IASTStatement prev = null;
+ if (i > 0)
+ prev = statements[i - 1];
if (isCaseStatement(curr)) {
prevCase = curr;
}
@@ -102,6 +106,13 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
if (!fCheckLastCase && next == null) {
continue; // Last case and we don't care
}
+ // If this is the null statement, base the decision on the previous statement
+ // instead (if there is one). Null statements can sneak in via macros in cases
+ // where the macro expansion ends in a semicolon, and the macro use is followed
+ // by a semicolon as well.
+ if (curr instanceof IASTNullStatement && (prev != prevCase)) {
+ curr = prev;
+ }
if (!isProducedByMacroExpansion(prevCase) && isFallThroughStamement(curr)) {
IASTComment comment = null;
if (next != null) {
diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java
index 99da565912f..dab450839e5 100644
--- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java
+++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java
@@ -563,4 +563,18 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
loadCodeAndRun(code);
checkErrorLine(4, ER_ID);
}
+
+ // void foo() {
+ // switch (0) {
+ // case 0:
+ // return 42;;
+ // case 1:
+ // break;
+ // }
+ // }
+ public void testDoubleSemicolon_bug441714() {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ }
}

Back to the top