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 37a94f82168..db8cd981265 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,8 @@ import org.eclipse.cdt.core.dom.ast.IVariable; 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.ICPPDeferredFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.parser.util.AttributeUtil; @@ -245,6 +247,19 @@ public class UnusedSymbolInFileScopeChecker extends AbstractIndexAstChecker { filterOutByPlainName(externVariableDeclarations, plainName); filterOutByPlainName(staticVariableDeclarations, plainName); } + + if (binding instanceof ICPPDeferredFunction) { + // Function call inside a template - we don't know which overload(s) + // it might match, so to avoid false positives we consider all + // candidates to be potentially used. + ICPPFunction[] candidates = ((ICPPDeferredFunction) binding).getCandidates(); + if (candidates != null) { + for (ICPPFunction candidate : candidates) { + externFunctionDeclarations.remove(candidate); + staticFunctionDefinitions.remove(candidate); + } + } + } IASTNode parentNode = name.getParent(); 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 4849df42719..9b5f3e2bdb2 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 @@ -327,4 +327,20 @@ public class UnusedSymbolInFileScopeCheckerTest extends CheckerTestCase { loadCodeAndRun(getAboveComment()); checkNoErrors(); } + + // static void foo(int) {} + // static void foo(float) {} + // + // template + // void bar(T t) { + // foo(t); + // } + // + // int main() { + // bar(0); + // } + public void testOverloadedStaticFunctionUsedInTemplate_bug358694() throws IOException { + loadCodeAndRunCpp(getAboveComment()); + checkNoErrors(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPDeferredFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPDeferredFunction.java new file mode 100644 index 00000000000..e754c9b4c98 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPDeferredFunction.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * Represents a reference to a function which cannot be resolved + * because an argument depends on a template parameter. + * + * @since 5.6 + */ +public interface ICPPDeferredFunction extends ICPPFunction { + /** + * Returns the candidate functions the reference might resolve to + * after template instantiation. + */ + public ICPPFunction[] getCandidates(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java index 6f56b9210a9..db8cc030f9c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java @@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredFunction; 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; @@ -25,7 +26,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType; * Represents a reference to a (member) function (instance), which cannot be resolved because * an argument depends on a template parameter. A compiler would resolve it during instantiation. */ -public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFunction, ICPPComputableFunction { +public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPDeferredFunction, ICPPComputableFunction { private static final ICPPFunctionType FUNCTION_TYPE= new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY); @@ -63,6 +64,7 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFuncti fCandidates = candidates; } + @Override public ICPPFunction[] getCandidates() { return fCandidates; }