mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 376790 - Codan should not issue warnings for unused variables and
functions that have attribute unused
This commit is contained in:
parent
249589c28c
commit
ae7dc29df9
9 changed files with 91 additions and 49 deletions
|
@ -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<IBinding, IASTDeclarator> externFunctionDeclarations = new HashMap<IBinding, IASTDeclarator>();
|
||||
private Map<IBinding, IASTDeclarator> staticFunctionDeclarations = new HashMap<IBinding, IASTDeclarator>();
|
||||
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue