Fixed false positives about const correctness caused by incorrect handling of default arguments
This commit is contained in:
parent
f803a18d50
commit
ea601ef2b0
|
@ -1280,6 +1280,29 @@ static unsigned int countParameters(const Token *tok)
|
|||
return numpar;
|
||||
}
|
||||
|
||||
static unsigned int countMinArgs(const Token* argList)
|
||||
{
|
||||
if (!argList)
|
||||
return 0;
|
||||
|
||||
argList = argList->next();
|
||||
if (argList->str() == ")")
|
||||
return 0;
|
||||
|
||||
unsigned int count = 1;
|
||||
for (; argList; argList = argList->next()) {
|
||||
if (argList->link() && Token::Match(argList, "(|[|{|<"))
|
||||
argList = argList->link();
|
||||
else if (argList->str() == ",")
|
||||
count++;
|
||||
else if (argList->str() == "=")
|
||||
return count-1;
|
||||
else if (argList->str() == ")")
|
||||
break;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok)
|
||||
{
|
||||
unsigned int args = countParameters(tok);
|
||||
|
@ -1287,7 +1310,7 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok)
|
|||
for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
||||
/** @todo we need to look at the argument types when there are overloaded functions
|
||||
* with the same number of arguments */
|
||||
if (func->tokenDef->str() == tok->str() && func->argCount() == args) {
|
||||
if (func->tokenDef->str() == tok->str() && (func->argCount() == args || (func->argCount() > args && countMinArgs(func->argDef) <= args))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1321,7 +1344,7 @@ bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok)
|
|||
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
||||
/** @todo we need to look at the argument types when there are overloaded functions
|
||||
* with the same number of arguments */
|
||||
if (func->tokenDef->str() == tok->str() && func->argCount() == args) {
|
||||
if (func->tokenDef->str() == tok->str() && (func->argCount() == args || (func->argCount() > args && countMinArgs(func->argDef) <= args))) {
|
||||
matches++;
|
||||
if (func->isConst)
|
||||
consts++;
|
||||
|
|
|
@ -134,6 +134,7 @@ private:
|
|||
TEST_CASE(const56); // ticket #3149
|
||||
TEST_CASE(const57); // ticket #2669
|
||||
TEST_CASE(const58); // ticket #2698
|
||||
TEST_CASE(const_handleDefaultParameters);
|
||||
TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
|
||||
TEST_CASE(assigningArrayElementIsNotAConstOperation);
|
||||
TEST_CASE(constoperator1); // operator< can often be const
|
||||
|
@ -4318,6 +4319,40 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:3]: (style, inconclusive) Technically the member function 'MyObject::foo' can be const.\n", errout.str());
|
||||
}
|
||||
|
||||
void const_handleDefaultParameters() {
|
||||
checkConst("struct Foo {\n"
|
||||
" void foo1(int i, int j = 0) {\n"
|
||||
" return func(this);\n"
|
||||
" }\n"
|
||||
" int bar1() {\n"
|
||||
" return foo1(1);\n"
|
||||
" }\n"
|
||||
" int bar2() {\n"
|
||||
" return foo1(1, 2);\n"
|
||||
" }\n"
|
||||
" int bar3() {\n"
|
||||
" return foo1(1, 2, 3);\n"
|
||||
" }\n"
|
||||
" int bar4() {\n"
|
||||
" return foo1();\n"
|
||||
" }\n"
|
||||
" void foo2(int i = 0) {\n"
|
||||
" return func(this);\n"
|
||||
" }\n"
|
||||
" int bar5() {\n"
|
||||
" return foo2();\n"
|
||||
" }\n"
|
||||
" void foo3() {\n"
|
||||
" return func(this);\n"
|
||||
" }\n"
|
||||
" int bar6() {\n"
|
||||
" return foo3();\n"
|
||||
" }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:11]: (style, inconclusive) Technically the member function 'Foo::bar3' can be const.\n"
|
||||
"[test.cpp:14]: (style, inconclusive) Technically the member function 'Foo::bar4' can be const.\n", errout.str());
|
||||
}
|
||||
|
||||
void assigningPointerToPointerIsNotAConstOperation() {
|
||||
checkConst("struct s\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue