diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties index 6ba43171f76..44fcb0651d3 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties @@ -9,17 +9,17 @@ # Alena Laskavaia - initial API and implementation ############################################################################### CaseBreakChecker_DefaultNoBreakCommentDescription=Comment text to suppress the problem: -CaseBreakChecker_EmptyCaseDescription=Check also empty case statement (except if last) -CaseBreakChecker_LastCaseDescription=Check also the last case statement +CaseBreakChecker_EmptyCaseDescription=Check also empty 'case' statement (except if last) +CaseBreakChecker_LastCaseDescription=Check also the last 'case' statement CatchByReference_ReportForUnknownType=Report a problem if type cannot be resolved NamingConventionFunctionChecker_LabelNamePattern=Name Pattern NamingConventionFunctionChecker_ParameterMethods=Also check C++ method names ReturnChecker_Param0=Also check functions with implicit return value GenericParameter_ParameterExceptions=Exceptions (value of the problem argument) GenericParameter_ParameterExceptionsItem=Value of the argument -StatementHasNoEffectChecker_ParameterMacro=Report problem in statements that comes from macro expansion -SuggestedParenthesisChecker_SuggestParanthesesAroundNot=Suggest parenthesis around not operator -SuspiciousSemicolonChecker_ParamAfterElse=Report an error if semicolon is right after else statement +StatementHasNoEffectChecker_ParameterMacro=Report problem in statements that come from macro expansion +SuggestedParenthesisChecker_SuggestParanthesesAroundNot=Suggest parenthesis around 'not' operator +SuspiciousSemicolonChecker_ParamAfterElse=Report an error if semicolon is right after 'else' statement SuspiciousSemicolonChecker_ParamElse=Do not report an error after 'if' when 'else' exists ProblemBindingChecker_Candidates=Candidates are: diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java index ed023fb8870..f1d39829241 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java @@ -57,9 +57,7 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { if (stmt instanceof IASTExpressionStatement) { IASTExpression expression = ((IASTExpressionStatement) stmt).getExpression(); if (hasNoEffect(expression)) { - boolean inMacro = CxxAstUtils.getInstance().isInMacro(expression); - boolean shouldReportInMacro = shouldReportInMacro(); - if (inMacro && !shouldReportInMacro) + if (!shouldReportInMacro() && CxxAstUtils.isInMacro(expression)) return PROCESS_SKIP; String arg = expression.getRawSignature(); if (!isFilteredArg(arg)) diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/UnusedSymbolInFileScopeChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/UnusedSymbolInFileScopeChecker.java index 8341c1a9a9d..54390de9ece 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/UnusedSymbolInFileScopeChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/UnusedSymbolInFileScopeChecker.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Map.Entry; import org.eclipse.cdt.codan.checkers.CodanCheckersActivator; +import org.eclipse.cdt.codan.core.cxx.CxxAstUtils; import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker; import org.eclipse.cdt.codan.core.model.IProblem; import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy; @@ -55,6 +56,7 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { public static final String ER_UNUSED_VARIABLE_DECLARATION_ID = "org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem"; //$NON-NLS-1$ public static final String ER_UNUSED_FUNCTION_DECLARATION_ID = "org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem"; //$NON-NLS-1$ public static final String ER_UNUSED_STATIC_FUNCTION_ID = "org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem"; //$NON-NLS-1$ + public static final String PARAM_MACRO_ID = "macro"; //$NON-NLS-1$ public static final String PARAM_EXCEPT_ARG_LIST = "exceptions"; //$NON-NLS-1$ private Map externFunctionDeclarations = new HashMap(); @@ -72,6 +74,7 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { @Override public void initPreferences(IProblemWorkingCopy problem) { super.initPreferences(problem); + addPreference(problem, PARAM_MACRO_ID, CheckersMessages.StatementHasNoEffectChecker_ParameterMacro, Boolean.TRUE); if (problem.getId().equals(ER_UNUSED_VARIABLE_DECLARATION_ID)) { unusedVariableProblem = problem; ListProblemPreference pref = addListPreference(problem, PARAM_EXCEPT_ARG_LIST, @@ -132,41 +135,51 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { int storageClass = simpleDeclaration.getDeclSpecifier().getStorageClass(); if (binding instanceof IFunction) { - if (storageClass == IASTDeclSpecifier.sc_extern || storageClass == IASTDeclSpecifier.sc_unspecified) { - externFunctionDeclarations.put(binding, decl); - } else if (storageClass == IASTDeclSpecifier.sc_static) { - staticFunctionDeclarations.put(binding, decl); - } - } else if (binding instanceof IVariable) { - if (storageClass == IASTDeclSpecifier.sc_extern) { - // Initializer makes "extern" declaration to become definition do not count these - if (decl.getInitializer() == null) { - externVariableDeclarations.put(binding, decl); + if (storageClass == IASTDeclSpecifier.sc_extern || + storageClass == IASTDeclSpecifier.sc_unspecified) { + if (shouldReportInMacro(ER_UNUSED_FUNCTION_DECLARATION_ID) || + !CxxAstUtils.isInMacro(astName)) { + externFunctionDeclarations.put(binding, decl); } } else if (storageClass == IASTDeclSpecifier.sc_static) { - IType type = ((IVariable) binding).getType(); - // Account for class constructor and avoid possible false positive - if (!(type instanceof ICPPClassType) && !(type instanceof IProblemType)) { - // Check if initializer disqualifies it - IASTInitializer initializer = decl.getInitializer(); - IASTInitializerClause clause = null; - if (initializer instanceof IASTEqualsInitializer) { - IASTEqualsInitializer equalsInitializer = (IASTEqualsInitializer) initializer; - clause = equalsInitializer.getInitializerClause(); - } else if (initializer instanceof ICPPASTConstructorInitializer) { - ICPPASTConstructorInitializer constructorInitializer = (ICPPASTConstructorInitializer) initializer; - IASTInitializerClause[] args = constructorInitializer.getArguments(); - if (args.length == 1) - clause = args[0]; + if (shouldReportInMacro(ER_UNUSED_STATIC_FUNCTION_ID) || + !CxxAstUtils.isInMacro(astName)) { + staticFunctionDeclarations.put(binding, decl); + } + } + } else if (binding instanceof IVariable) { + if (shouldReportInMacro(ER_UNUSED_VARIABLE_DECLARATION_ID) || + !CxxAstUtils.isInMacro(astName)) { + if (storageClass == IASTDeclSpecifier.sc_extern) { + // Initializer makes "extern" declaration to become definition do not count these + if (decl.getInitializer() == null) { + externVariableDeclarations.put(binding, decl); } - if (clause instanceof IASTLiteralExpression) { - IASTLiteralExpression literalExpression = (IASTLiteralExpression) clause; - String literal = literalExpression.toString(); - if (isFilteredOut(literal, unusedVariableProblem, PARAM_EXCEPT_ARG_LIST)) - continue; + } else if (storageClass == IASTDeclSpecifier.sc_static) { + IType type = ((IVariable) binding).getType(); + // Account for class constructor and avoid possible false positive + if (!(type instanceof ICPPClassType) && !(type instanceof IProblemType)) { + // Check if initializer disqualifies it + IASTInitializer initializer = decl.getInitializer(); + IASTInitializerClause clause = null; + if (initializer instanceof IASTEqualsInitializer) { + IASTEqualsInitializer equalsInitializer = (IASTEqualsInitializer) initializer; + clause = equalsInitializer.getInitializerClause(); + } else if (initializer instanceof ICPPASTConstructorInitializer) { + ICPPASTConstructorInitializer constructorInitializer = (ICPPASTConstructorInitializer) initializer; + IASTInitializerClause[] args = constructorInitializer.getArguments(); + if (args.length == 1) + clause = args[0]; + } + if (clause instanceof IASTLiteralExpression) { + IASTLiteralExpression literalExpression = (IASTLiteralExpression) clause; + String literal = literalExpression.toString(); + if (isFilteredOut(literal, unusedVariableProblem, PARAM_EXCEPT_ARG_LIST)) + continue; + } + + staticVariableDeclarations.put(binding, decl); } - - staticVariableDeclarations.put(binding, decl); } } } @@ -315,7 +328,7 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { clearCandidates(); // release memory } - public boolean isFilteredOut(String arg, IProblem problem, String exceptionListParamId) { + private boolean isFilteredOut(String arg, IProblem problem, String exceptionListParamId) { Object[] arr = (Object[]) getPreference(problem, exceptionListParamId); for (int i = 0; i < arr.length; i++) { String str = (String) arr[i]; @@ -325,4 +338,7 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { return false; } + private boolean shouldReportInMacro(String errorId) { + return (Boolean) getPreference(getProblemById(errorId, getFile()), PARAM_MACRO_ID); + } } diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java index b297756c364..e7214b3016d 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java @@ -121,7 +121,7 @@ public final class CxxAstUtils { return (IType) typeName; } - public boolean isInMacro(IASTNode node) { + public static boolean isInMacro(IASTNode node) { IASTNodeSelector nodeSelector = node.getTranslationUnit().getNodeSelector(node.getTranslationUnit().getFilePath()); IASTFileLocation fileLocation = node.getFileLocation(); IASTPreprocessorMacroExpansion macro = nodeSelector.findEnclosingMacroExpansion(fileLocation.getNodeOffset(),