1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 376790 - Codan should not issue warnings for unused variables and

functions that have attribute unused
This commit is contained in:
Sergey Prigogin 2012-04-13 15:49:10 -07:00
parent 249589c28c
commit ae7dc29df9
9 changed files with 91 additions and 49 deletions

View file

@ -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

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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() {

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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);