From ae7dc29df93774dff806a2f8f80b43d02c8adc6d Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 13 Apr 2012 15:49:10 -0700 Subject: Bug 376790 - Codan should not issue warnings for unused variables and functions that have attribute unused --- .../checkers/UnusedSymbolInFileScopeChecker.java | 15 ++++-- .../UnusedSymbolInFileScopeCheckerTest.java | 12 ++++- .../cdt/core/parser/util/AttributeUtil.java | 60 ++++++++++++++++++++++ .../cdt/internal/core/dom/parser/ASTAttribute.java | 38 -------------- .../cdt/internal/core/dom/parser/c/CFunction.java | 3 +- .../cdt/internal/core/dom/parser/c/CVisitor.java | 3 +- .../internal/core/dom/parser/cpp/CPPFunction.java | 3 +- .../core/dom/parser/cpp/CPPFunctionTemplate.java | 3 +- .../core/dom/parser/cpp/semantics/CPPVisitor.java | 3 +- 9 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/AttributeUtil.java 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 b22e9f26902..9c34d78659a 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 @@ -48,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.parser.util.AttributeUtil; /** * Checker looking for unused function or variable declarations. @@ -58,6 +59,7 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { 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 static final String[] ATTRIBUTE_UNUSED = new String[] { "__unused__", "unused" }; //$NON-NLS-1$//$NON-NLS-2$ private Map externFunctionDeclarations = new HashMap(); private Map staticFunctionDeclarations = new HashMap(); @@ -130,6 +132,8 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { IASTDeclarator[] declarators = simpleDeclaration.getDeclarators(); for (IASTDeclarator decl : declarators) { + if (AttributeUtil.hasAttribute(decl, ATTRIBUTE_UNUSED)) + continue; IASTName astName = decl.getName(); if (astName != null) { IBinding binding = astName.resolveBinding(); @@ -191,14 +195,15 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { // definitions IASTFunctionDefinition definition = (IASTFunctionDefinition) element; - IASTName astName = definition.getDeclarator().getName(); + IASTFunctionDeclarator declarator = definition.getDeclarator(); + IASTName astName = declarator.getName(); if (astName != null) { IBinding binding = astName.resolveBinding(); - if (definition.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_static) { - if (!(astName instanceof ICPPASTQualifiedName)) { - staticFunctionDefinitions.put(binding, definition.getDeclarator()); - } + if (definition.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_static && + !(astName instanceof ICPPASTQualifiedName) && + !AttributeUtil.hasAttribute(declarator, ATTRIBUTE_UNUSED)) { + staticFunctionDefinitions.put(binding, declarator); } // externFunctionDeclarators filter out diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java index 4cd1d7964fa..7bb967ed071 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 Andrew Gvozdev and others. + * Copyright (c) 2011, 2012 Andrew Gvozdev and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -307,4 +307,14 @@ public class UnusedSymbolInFileScopeCheckerTest extends CheckerTestCase { checkNoErrors(); } + // static int v1 __attribute__((unused)); + // int f1() __attribute__((__unused__)); + // extern int f2() __attribute__((unused)); + // static void f3() __attribute__((unused)); + // static void f4() __attribute__((unused)); + // static void f4() __attribute__((unused)) {} + public void testAttributeUnused() throws IOException { + loadCodeAndRun(getAboveComment()); + checkNoErrors(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/AttributeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/AttributeUtil.java new file mode 100644 index 00000000000..53c22374665 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/AttributeUtil.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2012 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.parser.util; + +import org.eclipse.cdt.core.dom.ast.IASTAttribute; +import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner; +import org.eclipse.cdt.core.dom.ast.IASTToken; + +/** + * Collection of static methods for dealing with attributes. + * @see org.eclipse.cdt.core.dom.ast.IASTAttribute + * @see org.eclipse.cdt.core.dom.ast.IASTAttributeOwner + * @since 5.4 + */ +public class AttributeUtil { + private static final String[] ATTRIBUTE_NORETURN = new String[] { "__noreturn__", "noreturn" }; //$NON-NLS-1$//$NON-NLS-2$ + + // Not instantiatable. + private AttributeUtil() {} + + /** + * Returns {@code true} if a declarator has an attribute with one of the given names. + * The {@code names} array is assumed to be small. + */ + public static boolean hasAttribute(IASTAttributeOwner node, String[] names) { + IASTAttribute[] attributes = node.getAttributes(); + for (IASTAttribute attribute : attributes) { + char[] name = attribute.getName(); + for (int i = 0; i < names.length; i++) { + if (CharArrayUtils.equals(name, names[i])) + return true; + } + } + return false; + } + + /** + * Returns {@code true} if the node has a "noreturn" or "__noreturn__" attribute. + */ + public static boolean hasNoreturnAttribute(IASTAttributeOwner node) { + return hasAttribute(node, ATTRIBUTE_NORETURN); + } + + /** + * Returns character representation of the attribute argument, or {@code null} if the attribute + * has zero or more than one argument. + */ + public static char[] getSimpleArgument(IASTAttribute attribute) { + IASTToken argumentClause = attribute.getArgumentClause(); + return argumentClause == null ? null : argumentClause.getTokenCharImage(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAttribute.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAttribute.java index d1093ea9347..7cb00efe5c2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAttribute.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAttribute.java @@ -12,16 +12,12 @@ package org.eclipse.cdt.internal.core.dom.parser; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTAttribute; -import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner; import org.eclipse.cdt.core.dom.ast.IASTToken; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; /** * Base class for C and C++ attributes. */ public abstract class ASTAttribute extends ASTNode implements IASTAttribute { - private static final String[] NORETURN_ATTRIBUTES = new String[] { "__noreturn__", "noreturn" }; //$NON-NLS-1$//$NON-NLS-2$ - private final char[] name; private final IASTToken argumentClause; @@ -66,38 +62,4 @@ public abstract class ASTAttribute extends ASTNode implements IASTAttribute { return true; } - - /** - * Returns {@code true} if a declarator has an attribute with one of the given names. - * The {@code names} array is assumed to be small. - */ - public static boolean hasAttribute(IASTAttributeOwner node, String[] names) { - IASTAttribute[] attributes = node.getAttributes(); - for (IASTAttribute attribute : attributes) { - char[] name = attribute.getName(); - for (int i = 0; i < names.length; i++) { - if (CharArrayUtils.equals(name, names[i])) - return true; - } - } - return false; - } - - /** - * Returns {@code true} if the node has a "noreturn" or "__noreturn__" attribute. - */ - public static boolean hasNoreturnAttribute(IASTAttributeOwner node) { - return hasAttribute(node, NORETURN_ATTRIBUTES); - } - - /** - * Returns character representation of the attribute argument, or {@code null} if the attribute - * has zero or more than one argument. - */ - public static char[] getSimpleArgument(IASTAttribute attribute) { - IASTToken argumentClause = attribute.getArgumentClause(); - if (argumentClause == null) - return null; - return argumentClause.getTokenCharImage(); - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java index 937a2dd0c6d..16362419e82 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java @@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTAttribute; @@ -488,7 +489,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu @Override public boolean isNoReturn() { IASTFunctionDeclarator dtor = getPreferredDtor(); - return dtor != null && ASTAttribute.hasNoreturnAttribute(dtor); + return dtor != null && AttributeUtil.hasNoreturnAttribute(dtor); } protected IASTFunctionDeclarator getPreferredDtor() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index 520b9143c09..387e509d4c6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -90,6 +90,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.IContentAssistMatcher; @@ -1272,7 +1273,7 @@ public class CVisitor extends ASTQueries { for (IASTAttribute attribute : attributes) { char[] name = attribute.getName(); if (CharArrayUtils.equals(name, "__mode__") || CharArrayUtils.equals(name, "mode")) { //$NON-NLS-1$ //$NON-NLS-2$ - char[] mode = ASTAttribute.getSimpleArgument(attribute); + char[] mode = AttributeUtil.getSimpleArgument(attribute); if (CharArrayUtils.equals(mode, "__QI__") || CharArrayUtils.equals(mode, "QI")) { //$NON-NLS-1$ //$NON-NLS-2$ type = new CBasicType(IBasicType.Kind.eChar, basicType.isUnsigned() ? IBasicType.IS_UNSIGNED : IBasicType.IS_SIGNED); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index eee15bb797e..d05977e2226 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -45,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTAttribute; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; @@ -599,6 +600,6 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt @Override public boolean isNoReturn() { ICPPASTFunctionDeclarator dtor = getPreferredDtor(); - return dtor != null && ASTAttribute.hasNoreturnAttribute(dtor); + return dtor != null && AttributeUtil.hasNoreturnAttribute(dtor); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index 13bfb745b53..101e4926023 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTAttribute; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; @@ -344,7 +345,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition public boolean isNoReturn() { ICPPASTFunctionDeclarator fdecl= getFirstFunctionDtor(); if (fdecl != null) { - return ASTAttribute.hasNoreturnAttribute(fdecl); + return AttributeUtil.hasNoreturnAttribute(fdecl); } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 33c65cbd8fa..75218d30195 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -156,6 +156,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTAttribute; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; @@ -1854,7 +1855,7 @@ public class CPPVisitor extends ASTQueries { for (IASTAttribute attribute : attributes) { char[] name = attribute.getName(); if (CharArrayUtils.equals(name, "__mode__") || CharArrayUtils.equals(name, "mode")) { //$NON-NLS-1$ //$NON-NLS-2$ - char[] mode = ASTAttribute.getSimpleArgument(attribute); + char[] mode = AttributeUtil.getSimpleArgument(attribute); if (CharArrayUtils.equals(mode, "__QI__") || CharArrayUtils.equals(mode, "QI")) { //$NON-NLS-1$ //$NON-NLS-2$ type = new CPPBasicType(IBasicType.Kind.eChar, basicType.isUnsigned() ? IBasicType.IS_UNSIGNED : IBasicType.IS_SIGNED); -- cgit v1.2.3