Fixed false positives about const correctness caused by incorrect handling of default arguments

This commit is contained in:
PKEuS 2012-05-17 01:05:36 -07:00
parent f803a18d50
commit ea601ef2b0
2 changed files with 60 additions and 2 deletions

View File

@ -1280,6 +1280,29 @@ static unsigned int countParameters(const Token *tok)
return numpar; 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) bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok)
{ {
unsigned int args = countParameters(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) { 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 /** @todo we need to look at the argument types when there are overloaded functions
* with the same number of arguments */ * 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; 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) { for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
/** @todo we need to look at the argument types when there are overloaded functions /** @todo we need to look at the argument types when there are overloaded functions
* with the same number of arguments */ * 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++; matches++;
if (func->isConst) if (func->isConst)
consts++; consts++;

View File

@ -134,6 +134,7 @@ private:
TEST_CASE(const56); // ticket #3149 TEST_CASE(const56); // ticket #3149
TEST_CASE(const57); // ticket #2669 TEST_CASE(const57); // ticket #2669
TEST_CASE(const58); // ticket #2698 TEST_CASE(const58); // ticket #2698
TEST_CASE(const_handleDefaultParameters);
TEST_CASE(assigningPointerToPointerIsNotAConstOperation); TEST_CASE(assigningPointerToPointerIsNotAConstOperation);
TEST_CASE(assigningArrayElementIsNotAConstOperation); TEST_CASE(assigningArrayElementIsNotAConstOperation);
TEST_CASE(constoperator1); // operator< can often be const 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()); 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() { void assigningPointerToPointerIsNotAConstOperation() {
checkConst("struct s\n" checkConst("struct s\n"
"{\n" "{\n"