* Include detecting variadic template functions by matching against endTok instead of startTok. * Add argument count check for variadic (template) member functions.
This commit is contained in:
parent
a623168942
commit
bc5ec38149
|
@ -1925,7 +1925,9 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const
|
|||
else
|
||||
break;
|
||||
}
|
||||
if (argsPassed == func.argCount() || (argsPassed < func.argCount() && argsPassed >= func.minArgCount()))
|
||||
if (argsPassed == func.argCount() ||
|
||||
(func.isVariadic() && argsPassed >= (func.argCount() - 1)) ||
|
||||
(argsPassed < func.argCount() && argsPassed >= func.minArgCount()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3681,8 +3681,8 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, symbolDatabase->mSettings);
|
||||
|
||||
if (tok->str() == ")") {
|
||||
// check for a variadic function
|
||||
if (Token::simpleMatch(startTok, "..."))
|
||||
// check for a variadic function or a variadic template function
|
||||
if (Token::simpleMatch(endTok, "..."))
|
||||
isVariadic(true);
|
||||
|
||||
break;
|
||||
|
|
|
@ -171,6 +171,8 @@ private:
|
|||
TEST_CASE(const66); // ticket #7714
|
||||
TEST_CASE(const67); // ticket #9193
|
||||
TEST_CASE(const68); // ticket #6471
|
||||
TEST_CASE(const69); // ticket #9806
|
||||
TEST_CASE(const70); // variadic template can receive more arguments than in its definition
|
||||
TEST_CASE(const_handleDefaultParameters);
|
||||
TEST_CASE(const_passThisToMemberOfOtherClass);
|
||||
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
|
||||
|
@ -5534,6 +5536,38 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void const69() { // #9806
|
||||
checkConst("struct A {\n"
|
||||
" int a = 0;\n"
|
||||
" template <typename... Args> void call(const Args &... args) { a = 1; }\n"
|
||||
" template <typename T, typename... Args> auto call(const Args &... args) -> T {\n"
|
||||
" a = 2;\n"
|
||||
" return T{};\n"
|
||||
" }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct B : public A {\n"
|
||||
" void test() {\n"
|
||||
" call();\n"
|
||||
" call<int>(1, 2, 3);\n"
|
||||
" }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void const70() {
|
||||
checkConst("struct A {\n"
|
||||
" template <typename... Args> void call(Args ... args) {\n"
|
||||
" func(this);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" void test() {\n"
|
||||
" call(1, 2);\n"
|
||||
" }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void const_handleDefaultParameters() {
|
||||
checkConst("struct Foo {\n"
|
||||
" void foo1(int i, int j = 0) {\n"
|
||||
|
|
Loading…
Reference in New Issue