Fixed #4701 (false positive unusedFunction when using templates)
This commit is contained in:
parent
5ce1933687
commit
9b4f6a6b3d
|
@ -111,6 +111,10 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
|
||||||
funcname = tok->next();
|
funcname = tok->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (Token::Match(tok->next(), "%var% <") && Token::simpleMatch(tok->linkAt(2), "> (")) {
|
||||||
|
funcname = tok->next();
|
||||||
|
}
|
||||||
|
|
||||||
else if (Token::Match(tok, "[;{}.,()[=+-/&|!?:] %var% [(),;:}]"))
|
else if (Token::Match(tok, "[;{}.,()[=+-/&|!?:] %var% [(),;:}]"))
|
||||||
funcname = tok->next();
|
funcname = tok->next();
|
||||||
|
|
||||||
|
@ -128,8 +132,11 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// funcname ( => Assert that the end parentheses isn't followed by {
|
// funcname ( => Assert that the end parentheses isn't followed by {
|
||||||
if (Token::Match(funcname, "%var% (")) {
|
if (Token::Match(funcname, "%var% (|<")) {
|
||||||
if (Token::Match(funcname->linkAt(1), ") const|throw|{"))
|
const Token *ftok = funcname->next();
|
||||||
|
if (ftok->str() == "<")
|
||||||
|
ftok = ftok->link();
|
||||||
|
if (Token::Match(ftok->linkAt(1), ") const|throw|{"))
|
||||||
funcname = NULL;
|
funcname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ private:
|
||||||
TEST_CASE(functionpointer);
|
TEST_CASE(functionpointer);
|
||||||
TEST_CASE(template1);
|
TEST_CASE(template1);
|
||||||
TEST_CASE(template2);
|
TEST_CASE(template2);
|
||||||
|
TEST_CASE(template3);
|
||||||
TEST_CASE(throwIsNotAFunction);
|
TEST_CASE(throwIsNotAFunction);
|
||||||
TEST_CASE(unusedError);
|
TEST_CASE(unusedError);
|
||||||
TEST_CASE(unusedMain);
|
TEST_CASE(unusedMain);
|
||||||
|
@ -171,6 +172,17 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template3() { // #4701
|
||||||
|
check("class X {\n"
|
||||||
|
"public:\n"
|
||||||
|
" void bar() { foo<int>(0); }\n"
|
||||||
|
"private:\n"
|
||||||
|
" template<typename T> void foo( T t ) const;\n"
|
||||||
|
"};\n"
|
||||||
|
"template<typename T> void X::foo( T t ) const { }\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void throwIsNotAFunction() {
|
void throwIsNotAFunction() {
|
||||||
check("struct A {void f() const throw () {}}; int main() {A a; a.f();}");
|
check("struct A {void f() const throw () {}}; int main() {A a; a.f();}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
Loading…
Reference in New Issue