Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/codan
diff options
context:
space:
mode:
authorMarc-Andre Laperle2018-09-22 04:46:25 +0000
committerMarc-André Laperle2018-10-12 02:43:20 +0000
commitefbda46cba9dbb17eaebf74013021ea1ab8114fb (patch)
tree3052982746c8360e193ddd8753aef3b5ec73b51a /codan
parent8492296d24dfacd63f21972fd7e91ffd806b250c (diff)
downloadorg.eclipse.cdt-efbda46cba9dbb17eaebf74013021ea1ab8114fb.tar.gz
org.eclipse.cdt-efbda46cba9dbb17eaebf74013021ea1ab8114fb.tar.xz
org.eclipse.cdt-efbda46cba9dbb17eaebf74013021ea1ab8114fb.zip
Bug 389577 - False positive "Unused static function"
Add handling of constructor/destructor attributes and some improvement when functions were previously declared but not defined as used. Change-Id: I7537bc87c6c4bc5b294d8e15fe5b42c92b3f2974 Signed-off-by: Marc-Andre Laperle <malaperle@gmail.com>
Diffstat (limited to 'codan')
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/UnusedSymbolInFileScopeChecker.java36
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java19
2 files changed, 47 insertions, 8 deletions
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 ebb2fca2dbc..607a1e6f63e 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
@@ -13,10 +13,12 @@ package org.eclipse.cdt.codan.internal.checkers;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
import org.eclipse.cdt.codan.core.cxx.CxxAstUtils;
@@ -26,6 +28,7 @@ import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.codan.core.param.ListProblemPreference;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
@@ -62,13 +65,17 @@ 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$
+ /*
+ * Various attributes that when present for a symbol should make it considered as used.
+ */
+ private static final String[] USAGE_ATTRIBUTES = new String[] { "__unused__", "unused", "constructor", "destructor" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
private Map<IBinding, IASTDeclarator> externFunctionDeclarations = new HashMap<IBinding, IASTDeclarator>();
private Map<IBinding, IASTDeclarator> staticFunctionDeclarations = new HashMap<IBinding, IASTDeclarator>();
private Map<IBinding, IASTDeclarator> staticFunctionDefinitions = new HashMap<IBinding, IASTDeclarator>();
private Map<IBinding, IASTDeclarator> externVariableDeclarations = new HashMap<IBinding, IASTDeclarator>();
private Map<IBinding, IASTDeclarator> staticVariableDeclarations = new HashMap<IBinding, IASTDeclarator>();
+ private Set<IBinding> declarationsWithUsageAttributes = new HashSet<>();
private IProblemWorkingCopy unusedVariableProblem = null;
@Override
@@ -118,6 +125,7 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker {
filterOutUsedElements(ast);
reportProblems();
}
+ declarationsWithUsageAttributes.clear();
}
private void collectCandidates(IASTTranslationUnit ast) {
@@ -134,16 +142,15 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker {
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) element;
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
- if (AttributeUtil.hasAttribute(declSpec, ATTRIBUTE_UNUSED)) {
- return PROCESS_SKIP;
- }
+ boolean hasUsageAttrib = hasUsageAttribute(declSpec);
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();
+ if (hasUsageAttrib || hasUsageAttribute(decl)) {
+ declarationsWithUsageAttributes.add(binding);
+ }
int storageClass = simpleDeclaration.getDeclSpecifier().getStorageClass();
if (binding instanceof IFunction) {
@@ -206,10 +213,12 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker {
IASTName astName = declarator.getName();
if (astName != null) {
IBinding binding = astName.resolveBinding();
+ if (hasUsageAttribute(definition.getDeclSpecifier())) {
+ declarationsWithUsageAttributes.add(binding);
+ }
if (definition.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_static &&
- !(astName instanceof ICPPASTQualifiedName) &&
- !AttributeUtil.hasAttribute(declarator, ATTRIBUTE_UNUSED)) {
+ !(astName instanceof ICPPASTQualifiedName)) {
staticFunctionDefinitions.put(binding, declarator);
}
@@ -222,6 +231,9 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker {
return PROCESS_SKIP;
}
+ private boolean hasUsageAttribute(IASTAttributeOwner attributeOwner) {
+ return AttributeUtil.hasAttribute(attributeOwner, USAGE_ATTRIBUTES);
+ }
});
} catch (Exception e) {
CodanCheckersActivator.log(e);
@@ -283,6 +295,14 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker {
staticVariableDeclarations.remove(binding);
}
+ if (declarationsWithUsageAttributes.contains(binding)) {
+ staticFunctionDeclarations.remove(binding);
+ externFunctionDeclarations.remove(binding);
+ staticFunctionDefinitions.remove(binding);
+ externVariableDeclarations.remove(binding);
+ staticVariableDeclarations.remove(binding);
+ }
+
if (!isAnyCandidate())
return PROCESS_ABORT;
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java
index 693c06435f5..270a66a7283 100644
--- a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java
@@ -315,9 +315,16 @@ public class UnusedSymbolInFileScopeCheckerTest extends CheckerTestCase {
// int f1() __attribute__((__unused__));
// extern int f2() __attribute__((unused));
// static void f3() __attribute__((unused));
+ // void f3() {}
// static void f4() __attribute__((unused));
// static void f4() __attribute__((unused)) {}
// static void __attribute__((unused)) f5();
+ // static void f6() __attribute__((unused));
+ // static void f6() {}
+ // static void __attribute__((unused)) f7();
+ // void f7() {}
+ // static void __attribute__((unused)) f8();
+ // static void f8() {}
public void testAttributeUnused() throws Exception {
loadCodeAndRunC(getAboveComment());
checkNoErrors();
@@ -326,6 +333,18 @@ public class UnusedSymbolInFileScopeCheckerTest extends CheckerTestCase {
checkNoErrors();
}
+ // static void __attribute__((constructor)) Ctor() {}
+ // static void __attribute__((destructor)) Dtor();
+ // static void Dtor2() __attribute__((destructor));
+ // static void Dtor3() __attribute__((destructor));
+ // static void Dtor() {}
+ // static void Dtor2() {}
+ // void Dtor3() {}
+ public void testAttributeConstructorDestructor_bug389577() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
// extern int* pxCurrentTCB;
//
// int main() {

Back to the top