Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java')
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java31
1 files changed, 31 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 ddaecb40e9e..c87a33737d9 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
@@ -37,12 +37,15 @@ import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.parser.StandardAttributes;
+import org.eclipse.cdt.core.parser.util.AttributeUtil;
public class CaseBreakChecker extends AbstractIndexAstChecker implements ICheckerWithPreferences {
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem"; //$NON-NLS-1$
public static final String PARAM_LAST_CASE = "last_case_param"; //$NON-NLS-1$
public static final String PARAM_EMPTY_CASE = "empty_case_param"; //$NON-NLS-1$
public static final String PARAM_NO_BREAK_COMMENT = "no_break_comment"; //$NON-NLS-1$
+ public static final String PARAM_ENABLE_FALLTHROUGH_QUICKFIX = "enable_fallthrough_quickfix_param"; //$NON-NLS-1$
public static final String DEFAULT_NO_BREAK_COMMENT = "no break"; //$NON-NLS-1$
private boolean fCheckLastCase; // Should we check the last case in the switch?
private boolean fCheckEmptyCase; // Should we check an empty case (a case without any statements within it)
@@ -106,6 +109,9 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
if (!fCheckLastCase && next == null) {
continue; // Last case and we don't care
}
+ if (next != null && hasValidFallthroughAttribute(curr)) {
+ continue; // Explicit fallthrough, do not analyse case further (not valid in last case)
+ }
// 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
@@ -168,6 +174,30 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
}
return true; // TODO
}
+
+ /**
+ * Checks whether {@code statement} (or its last inner statement if it
+ * is a compound statement) is a {@code IASTNullStatement} and has the
+ * C++ standard [[fallthrough]] attribute
+ *
+ * @param statement The {@code IASTStatement} to check
+ * @return {@code true} if the {@code statement} has the [[fallthrough]]
+ * attribute,
+ * {@code false} otherwise.
+ */
+ public boolean hasValidFallthroughAttribute(IASTStatement statement) {
+ IASTStatement lastStatement = statement;
+ while (lastStatement instanceof IASTCompoundStatement && lastStatement.getChildren().length > 0) {
+ IASTCompoundStatement compoundStatement = (IASTCompoundStatement) lastStatement;
+ IASTStatement[] nestedStatements = compoundStatement.getStatements();
+ lastStatement = nestedStatements[nestedStatements.length - 1];
+ }
+ if (lastStatement instanceof IASTNullStatement) {
+ if (AttributeUtil.hasAttribute(lastStatement, new String[] { StandardAttributes.FALLTHROUGH }))
+ return true;
+ }
+ return false;
+ }
}
private void reportProblem(IASTStatement curr) {
@@ -231,6 +261,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
DEFAULT_NO_BREAK_COMMENT);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE);
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE);
+ addPreference(problem, PARAM_ENABLE_FALLTHROUGH_QUICKFIX, CheckersMessages.CaseBreakChecker_EnableFallthroughQuickfixDescription, Boolean.FALSE);
}
@Override

Back to the top