mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
bug 343429: [checker] Checker to pinpoint unused static functions in a file
This commit is contained in:
parent
1c43fad405
commit
f1daf6235a
5 changed files with 862 additions and 311 deletions
|
@ -111,3 +111,15 @@ checker.name.AbstractClassCreation = Abstract class cannot be instantiated
|
||||||
problem.name.AbstractClassCreation = Abstract class cannot be instantiated
|
problem.name.AbstractClassCreation = Abstract class cannot be instantiated
|
||||||
problem.messagePattern.AbstractClassCreation = The type ''{0}'' must implement the inherited pure virtual method ''{1}''
|
problem.messagePattern.AbstractClassCreation = The type ''{0}'' must implement the inherited pure virtual method ''{1}''
|
||||||
problem.description.AbstractClassCreation = All inherited pure virtual methods must be implemented to allow instantiation of the class
|
problem.description.AbstractClassCreation = All inherited pure virtual methods must be implemented to allow instantiation of the class
|
||||||
|
|
||||||
|
checker.name.UnusedSymbolInFileScopeChecker = Unused symbols and declarations in file scope
|
||||||
|
problem.description.UnusedVariableDeclarationProblem = Finds unused global variable declarations in file scope
|
||||||
|
problem.messagePattern.UnusedVariableDeclarationProblem = Unused declaration of variable ''{0}''
|
||||||
|
problem.name.UnusedVariableDeclarationProblem = Unused variable declaration in file scope
|
||||||
|
problem.description.UnusedFunctionDeclarationProblem = Finds unused function declarations
|
||||||
|
problem.messagePattern.UnusedFunctionDeclarationProblem = Unused declaration of function ''{0}''
|
||||||
|
problem.name.UnusedFunctionDeclarationProblem = Unused function declaration
|
||||||
|
problem.description.UnusedStaticFunctionProblem = Finds static functions which cannot be possible used not being referenced inside the file
|
||||||
|
problem.messagePattern.UnusedStaticFunctionProblem = Unused static function ''{0}''
|
||||||
|
problem.name.UnusedStaticFunctionProblem = Unused static function
|
||||||
|
|
||||||
|
|
|
@ -349,5 +349,40 @@
|
||||||
name="%problem.name.AbstractClassCreation">
|
name="%problem.name.AbstractClassCreation">
|
||||||
</problem>
|
</problem>
|
||||||
</checker>
|
</checker>
|
||||||
|
<checker
|
||||||
|
class="org.eclipse.cdt.codan.internal.checkers.UnusedSymbolInFileScopeChecker"
|
||||||
|
id="org.eclipse.cdt.codan.internal.checkers.UnusedSymbolInFileScopeChecker"
|
||||||
|
name="%checker.name.UnusedSymbolInFileScopeChecker">
|
||||||
|
<problem
|
||||||
|
category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
|
||||||
|
defaultEnabled="true"
|
||||||
|
defaultSeverity="Warning"
|
||||||
|
description="%problem.description.UnusedVariableDeclarationProblem"
|
||||||
|
id="org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem"
|
||||||
|
messagePattern="%problem.messagePattern.UnusedVariableDeclarationProblem"
|
||||||
|
multiple="true"
|
||||||
|
name="%problem.name.UnusedVariableDeclarationProblem">
|
||||||
|
</problem>
|
||||||
|
<problem
|
||||||
|
category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
|
||||||
|
defaultEnabled="true"
|
||||||
|
defaultSeverity="Warning"
|
||||||
|
description="%problem.description.UnusedFunctionDeclarationProblem"
|
||||||
|
id="org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem"
|
||||||
|
messagePattern="%problem.messagePattern.UnusedFunctionDeclarationProblem"
|
||||||
|
multiple="true"
|
||||||
|
name="%problem.name.UnusedFunctionDeclarationProblem">
|
||||||
|
</problem>
|
||||||
|
<problem
|
||||||
|
category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
|
||||||
|
defaultEnabled="true"
|
||||||
|
defaultSeverity="Warning"
|
||||||
|
description="%problem.description.UnusedStaticFunctionProblem"
|
||||||
|
id="org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem"
|
||||||
|
messagePattern="%problem.messagePattern.UnusedStaticFunctionProblem"
|
||||||
|
multiple="true"
|
||||||
|
name="%problem.name.UnusedStaticFunctionProblem">
|
||||||
|
</problem>
|
||||||
|
</checker>
|
||||||
</extension>
|
</extension>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2011 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Andrew Gvozdev - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.codan.internal.checkers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
|
||||||
|
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
||||||
|
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IProblemType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checker looking for unused function or variable declarations.
|
||||||
|
*/
|
||||||
|
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$
|
||||||
|
|
||||||
|
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>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* org.eclipse.cdt.codan.core.model.ICheckerWithPreferences#initParameters
|
||||||
|
* (org.eclipse.cdt.codan.core.model.IProblemWorkingCopy)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initPreferences(IProblemWorkingCopy problem) {
|
||||||
|
super.initPreferences(problem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearCandidates() {
|
||||||
|
externFunctionDeclarations.clear();
|
||||||
|
staticFunctionDeclarations.clear();
|
||||||
|
staticFunctionDefinitions.clear();
|
||||||
|
externVariableDeclarations.clear();
|
||||||
|
staticVariableDeclarations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAnyCandidate() {
|
||||||
|
return externFunctionDeclarations.size() > 0 ||
|
||||||
|
staticFunctionDeclarations.size() > 0 ||
|
||||||
|
staticFunctionDefinitions.size() > 0 ||
|
||||||
|
externVariableDeclarations.size() > 0 ||
|
||||||
|
staticVariableDeclarations.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processAst(IASTTranslationUnit ast) {
|
||||||
|
if (ast.isHeaderUnit())
|
||||||
|
return;
|
||||||
|
|
||||||
|
clearCandidates();
|
||||||
|
collectCandidates(ast);
|
||||||
|
|
||||||
|
if (isAnyCandidate()) {
|
||||||
|
filterOutUsedElements(ast);
|
||||||
|
reportProblems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectCandidates(IASTTranslationUnit ast) {
|
||||||
|
try {
|
||||||
|
ast.accept(new ASTVisitor() {
|
||||||
|
{
|
||||||
|
shouldVisitDeclarations = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTDeclaration element) {
|
||||||
|
if (element instanceof IASTSimpleDeclaration) {
|
||||||
|
// declarations
|
||||||
|
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) element;
|
||||||
|
|
||||||
|
IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();
|
||||||
|
for (IASTDeclarator decl : declarators) {
|
||||||
|
IASTName astName = decl.getName();
|
||||||
|
if (astName != null) {
|
||||||
|
IBinding binding = astName.resolveBinding();
|
||||||
|
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) {
|
||||||
|
externVariableDeclarations.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)) {
|
||||||
|
staticVariableDeclarations.put(binding, decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PROCESS_SKIP;
|
||||||
|
} else if (element instanceof IASTFunctionDefinition) {
|
||||||
|
// definitions
|
||||||
|
IASTFunctionDefinition definition = (IASTFunctionDefinition) element;
|
||||||
|
|
||||||
|
IASTName astName = definition.getDeclarator().getName();
|
||||||
|
if (astName != null) {
|
||||||
|
IBinding binding = astName.resolveBinding();
|
||||||
|
|
||||||
|
if (definition.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_static) {
|
||||||
|
if (!(astName instanceof ICPPASTQualifiedName)) {
|
||||||
|
staticFunctionDefinitions.put(binding, definition.getDeclarator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// externFunctionDeclarators filter out
|
||||||
|
externFunctionDeclarations.remove(binding);
|
||||||
|
// staticFunctionDeclarators filter out
|
||||||
|
staticFunctionDeclarations.remove(binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PROCESS_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
CodanCheckersActivator.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterOutUsedElements(IASTTranslationUnit ast) {
|
||||||
|
try {
|
||||||
|
ast.accept(new ASTVisitor() {
|
||||||
|
{
|
||||||
|
shouldVisitNames = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTName name) {
|
||||||
|
IBinding binding = name.resolveBinding();
|
||||||
|
if (binding instanceof ICPPMethod)
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
|
||||||
|
IASTNode parentNode = name.getParent();
|
||||||
|
|
||||||
|
if (!(parentNode instanceof IASTFunctionDefinition || parentNode instanceof IASTFunctionDeclarator)) {
|
||||||
|
externFunctionDeclarations.remove(binding);
|
||||||
|
staticFunctionDefinitions.remove(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(parentNode instanceof IASTDeclarator)) {
|
||||||
|
externVariableDeclarations.remove(binding);
|
||||||
|
staticVariableDeclarations.remove(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isAnyCandidate())
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
CodanCheckersActivator.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTName getAstName(IASTDeclarator decl) {
|
||||||
|
IASTName astName = null;
|
||||||
|
do {
|
||||||
|
astName = decl.getName();
|
||||||
|
if (astName != null && astName.getSimpleID().length > 0)
|
||||||
|
return astName;
|
||||||
|
|
||||||
|
// resolve parenthesis if need to
|
||||||
|
decl = decl.getNestedDeclarator();
|
||||||
|
} while (decl != null);
|
||||||
|
|
||||||
|
return astName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reportProblems() {
|
||||||
|
List<IASTDeclarator> funcDeclarators = new ArrayList<IASTDeclarator>();
|
||||||
|
funcDeclarators.addAll(externFunctionDeclarations.values());
|
||||||
|
funcDeclarators.addAll(staticFunctionDeclarations.values());
|
||||||
|
for (IASTDeclarator symbol : funcDeclarators) {
|
||||||
|
IASTName astName = getAstName(symbol);
|
||||||
|
if (astName != null) {
|
||||||
|
String symbolName = new String(astName.getSimpleID());
|
||||||
|
reportProblem(ER_UNUSED_FUNCTION_DECLARATION_ID, astName, symbolName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IASTDeclarator> varDeclarators = new ArrayList<IASTDeclarator>();
|
||||||
|
varDeclarators.addAll(externVariableDeclarations.values());
|
||||||
|
varDeclarators.addAll(staticVariableDeclarations.values());
|
||||||
|
for (IASTDeclarator symbol : varDeclarators) {
|
||||||
|
IASTName astName = getAstName(symbol);
|
||||||
|
if (astName != null) {
|
||||||
|
String symbolName = new String(astName.getSimpleID());
|
||||||
|
reportProblem(ER_UNUSED_VARIABLE_DECLARATION_ID, astName, symbolName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IASTDeclarator> staticFuncDeclarators = new ArrayList<IASTDeclarator>();
|
||||||
|
staticFuncDeclarators.addAll(staticFunctionDefinitions.values());
|
||||||
|
for (IASTDeclarator symbol : staticFuncDeclarators) {
|
||||||
|
IASTName astName = getAstName(symbol);
|
||||||
|
if (astName != null) {
|
||||||
|
String symbolName = new String(astName.getSimpleID());
|
||||||
|
reportProblem(ER_UNUSED_STATIC_FUNCTION_ID, astName, symbolName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCandidates(); // release memory
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean runInEditor() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,247 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2011 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Andrew Gvozdev - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.codan.core.internal.checkers;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.codan.core.test.CheckerTestCase;
|
||||||
|
import org.eclipse.cdt.codan.internal.checkers.UnusedSymbolInFileScopeChecker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@see UnusedSymbolInFileScopeChecker} class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UnusedSymbolInFileScopeCheckerTest extends CheckerTestCase {
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
enableProblems(
|
||||||
|
UnusedSymbolInFileScopeChecker.ER_UNUSED_VARIABLE_DECLARATION_ID,
|
||||||
|
UnusedSymbolInFileScopeChecker.ER_UNUSED_FUNCTION_DECLARATION_ID,
|
||||||
|
UnusedSymbolInFileScopeChecker.ER_UNUSED_STATIC_FUNCTION_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// extern function declarations
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// int test_fun();
|
||||||
|
// extern int test_efun();
|
||||||
|
public void testExternFunction_Declaration_Unused() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
checkErrorLine(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// int test_fun();
|
||||||
|
// void fun() {
|
||||||
|
// test_fun();
|
||||||
|
// }
|
||||||
|
public void testExternFunction_Declaration_Used() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// void test_fun();
|
||||||
|
// void test_fun() {}
|
||||||
|
public void testExternFunction_Declaration_FollowedByDefinition() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// extern function definitions
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// void test_fun(void) {}
|
||||||
|
public void testExternFunction_Definition() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Static function declarations
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// static void test_fun(void);
|
||||||
|
public void testStaticFunction_Declaration_Unused() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void test_fun(void);
|
||||||
|
// static void test_fun(void) {}
|
||||||
|
public void testStaticFunction_Declaration_FollowedByDefinition() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void test_fun(void);
|
||||||
|
// void fun() {
|
||||||
|
// test_fun();
|
||||||
|
// }
|
||||||
|
public void testStaticFunction_Declaration_Used() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Static function definitions
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// static void test_fun(void) {}
|
||||||
|
public void testStaticFunction_Definition_Unused() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void test_fun(void);
|
||||||
|
// static void test_fun(void) {}
|
||||||
|
public void testStaticFunction_Definition_Unused_WithDeclaration() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void test_fun(void) {}
|
||||||
|
// void fun() {
|
||||||
|
// test_fun();
|
||||||
|
// }
|
||||||
|
public void testStaticFunction_Definition_Used() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// void fun() {
|
||||||
|
// test_fun();
|
||||||
|
// }
|
||||||
|
// static int test_fun(void) {}
|
||||||
|
public void testStaticFunction_Definition_UsedBeforeDefinition() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int test_fun(void) {}
|
||||||
|
// static int test_fun(int) {}
|
||||||
|
// void fun() {
|
||||||
|
// test_fun(0);
|
||||||
|
// }
|
||||||
|
public void testStaticFunction_Definition_Signature() throws IOException {
|
||||||
|
loadCodeAndRunCpp(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int test_fun(void) {}
|
||||||
|
// void fun() {
|
||||||
|
// int test_fun=0;
|
||||||
|
// }
|
||||||
|
public void testStaticFunction_Definition_SynonymLocalScope() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int test_fun(void) {}
|
||||||
|
// void fun(int test_fun) {
|
||||||
|
// }
|
||||||
|
public void testStaticFunction_Definition_SynonymArgs() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int (test_fun) ();
|
||||||
|
public void testStaticFunction_Definition_InParentheses() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Extern variables declaration
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// extern int test_var;
|
||||||
|
public void testExternVariable_Declaration_Unused() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// extern int test_var;
|
||||||
|
// void fun() {
|
||||||
|
// test_var=0;
|
||||||
|
// }
|
||||||
|
public void testExternVariable_Declaration_Used() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// extern int i,
|
||||||
|
// test_var;
|
||||||
|
public void testExternVariable_Declaration_Combined() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
checkErrorLine(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Extern variables definition
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// int test_var;
|
||||||
|
// int test_var2=0;
|
||||||
|
public void testExternVariable_Definition() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Static variables
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// static int test_var;
|
||||||
|
public void testStaticVariable_Unused() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int (*test_var)(float, char, char);
|
||||||
|
public void testStaticVariable_Unused_FunctionPointer() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkErrorLine(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int test_var;
|
||||||
|
// int i=test_var;
|
||||||
|
public void testStaticVariable_Used_GlobalScope() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static int test_var;
|
||||||
|
// void fun() {
|
||||||
|
// int i=test_var;
|
||||||
|
// }
|
||||||
|
public void testStaticVariable_Used_LocalScope() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// class Class;
|
||||||
|
// static Class test_var; // constructor is called here
|
||||||
|
public void testStaticVariable_Used_Constructor() throws IOException {
|
||||||
|
loadCodeAndRunCpp(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static X test_var; // avoid possible false positive, binding checker would complain anyway
|
||||||
|
public void testExternVariable_Declaration_IgnoreUnresolved() throws IOException {
|
||||||
|
loadCodeAndRun(getAboveComment());
|
||||||
|
checkNoErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import org.eclipse.cdt.codan.core.internal.checkers.ReturnStyleCheckerTest;
|
||||||
import org.eclipse.cdt.codan.core.internal.checkers.StatementHasNoEffectCheckerTest;
|
import org.eclipse.cdt.codan.core.internal.checkers.StatementHasNoEffectCheckerTest;
|
||||||
import org.eclipse.cdt.codan.core.internal.checkers.SuggestedParenthesisCheckerTest;
|
import org.eclipse.cdt.codan.core.internal.checkers.SuggestedParenthesisCheckerTest;
|
||||||
import org.eclipse.cdt.codan.core.internal.checkers.SuspiciousSemicolonCheckerTest;
|
import org.eclipse.cdt.codan.core.internal.checkers.SuspiciousSemicolonCheckerTest;
|
||||||
|
import org.eclipse.cdt.codan.core.internal.checkers.UnusedSymbolInFileScopeCheckerTest;
|
||||||
import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CreateLocalVariableQuickFixTest;
|
import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CreateLocalVariableQuickFixTest;
|
||||||
import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.SuggestedParenthesisQuickFixTest;
|
import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.SuggestedParenthesisQuickFixTest;
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ public class AutomatedIntegrationSuite extends TestSuite {
|
||||||
suite.addTestSuite(StatementHasNoEffectCheckerTest.class);
|
suite.addTestSuite(StatementHasNoEffectCheckerTest.class);
|
||||||
suite.addTestSuite(SuggestedParenthesisCheckerTest.class);
|
suite.addTestSuite(SuggestedParenthesisCheckerTest.class);
|
||||||
suite.addTestSuite(SuspiciousSemicolonCheckerTest.class);
|
suite.addTestSuite(SuspiciousSemicolonCheckerTest.class);
|
||||||
|
suite.addTestSuite(UnusedSymbolInFileScopeCheckerTest.class);
|
||||||
// framework
|
// framework
|
||||||
suite.addTest(CodanFastTestSuite.suite());
|
suite.addTest(CodanFastTestSuite.suite());
|
||||||
// quick fixes
|
// quick fixes
|
||||||
|
|
Loading…
Add table
Reference in a new issue