Skip to content

Commit bc5ec38

Browse files
authored
Fix #9806 (False positive: template function can be static) (cppcheck-opensource#2868)
* Include detecting variadic template functions by matching against endTok instead of startTok. * Add argument count check for variadic (template) member functions.
1 parent a623168 commit bc5ec38

3 files changed

Lines changed: 39 additions & 3 deletions

File tree

lib/checkclass.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1925,7 +1925,9 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const
19251925
else
19261926
break;
19271927
}
1928-
if (argsPassed == func.argCount() || (argsPassed < func.argCount() && argsPassed >= func.minArgCount()))
1928+
if (argsPassed == func.argCount() ||
1929+
(func.isVariadic() && argsPassed >= (func.argCount() - 1)) ||
1930+
(argsPassed < func.argCount() && argsPassed >= func.minArgCount()))
19291931
return true;
19301932
}
19311933
}

lib/symboldatabase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3681,8 +3681,8 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
36813681
argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, symbolDatabase->mSettings);
36823682

36833683
if (tok->str() == ")") {
3684-
// check for a variadic function
3685-
if (Token::simpleMatch(startTok, "..."))
3684+
// check for a variadic function or a variadic template function
3685+
if (Token::simpleMatch(endTok, "..."))
36863686
isVariadic(true);
36873687

36883688
break;

test/testclass.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ class TestClass : public TestFixture {
171171
TEST_CASE(const66); // ticket #7714
172172
TEST_CASE(const67); // ticket #9193
173173
TEST_CASE(const68); // ticket #6471
174+
TEST_CASE(const69); // ticket #9806
175+
TEST_CASE(const70); // variadic template can receive more arguments than in its definition
174176
TEST_CASE(const_handleDefaultParameters);
175177
TEST_CASE(const_passThisToMemberOfOtherClass);
176178
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
@@ -5534,6 +5536,38 @@ class TestClass : public TestFixture {
55345536
ASSERT_EQUALS("", errout.str());
55355537
}
55365538

5539+
void const69() { // #9806
5540+
checkConst("struct A {\n"
5541+
" int a = 0;\n"
5542+
" template <typename... Args> void call(const Args &... args) { a = 1; }\n"
5543+
" template <typename T, typename... Args> auto call(const Args &... args) -> T {\n"
5544+
" a = 2;\n"
5545+
" return T{};\n"
5546+
" }\n"
5547+
"};\n"
5548+
"\n"
5549+
"struct B : public A {\n"
5550+
" void test() {\n"
5551+
" call();\n"
5552+
" call<int>(1, 2, 3);\n"
5553+
" }\n"
5554+
"};");
5555+
ASSERT_EQUALS("", errout.str());
5556+
}
5557+
5558+
void const70() {
5559+
checkConst("struct A {\n"
5560+
" template <typename... Args> void call(Args ... args) {\n"
5561+
" func(this);\n"
5562+
" }\n"
5563+
"\n"
5564+
" void test() {\n"
5565+
" call(1, 2);\n"
5566+
" }\n"
5567+
"};");
5568+
ASSERT_EQUALS("", errout.str());
5569+
}
5570+
55375571
void const_handleDefaultParameters() {
55385572
checkConst("struct Foo {\n"
55395573
" void foo1(int i, int j = 0) {\n"

0 commit comments

Comments
 (0)