diff options
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.java | 31 |
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 |