Fixed #2282 (Improve check: Function can be const)
This commit is contained in:
parent
3527c04cfb
commit
980a90071c
|
@ -534,7 +534,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Token **funcStart, const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SymbolDatabase::argsMatch(const Token *first, const Token *second, const std::string &path, unsigned int depth) const
|
||||
bool SymbolDatabase::argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const
|
||||
{
|
||||
bool match = false;
|
||||
while (first->str() == second->str())
|
||||
|
@ -608,6 +608,14 @@ bool SymbolDatabase::argsMatch(const Token *first, const Token *second, const st
|
|||
}
|
||||
}
|
||||
|
||||
// nested class variable
|
||||
else if (depth == 0 && Token::Match(first->next(), "%var%") &&
|
||||
second->next()->str() == info->className && second->strAt(2) == "::" &&
|
||||
first->next()->str() == second->strAt(3))
|
||||
{
|
||||
second = second->tokAt(2);
|
||||
}
|
||||
|
||||
first = first->next();
|
||||
second = second->next();
|
||||
}
|
||||
|
@ -689,7 +697,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
|||
(*tok)->str() == "operator" &&
|
||||
func->tokenDef->str() == (*tok)->strAt(1))
|
||||
{
|
||||
if (argsMatch(func->tokenDef->tokAt(2), (*tok)->tokAt(3), path, path_length))
|
||||
if (argsMatch(info1, func->tokenDef->tokAt(2), (*tok)->tokAt(3), path, path_length))
|
||||
{
|
||||
func->hasBody = true;
|
||||
func->token = (*tok)->next();
|
||||
|
@ -700,7 +708,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
|||
(*tok)->previous()->str() == "~" &&
|
||||
func->tokenDef->str() == (*tok)->str())
|
||||
{
|
||||
if (argsMatch(func->tokenDef->next(), (*tok)->next(), path, path_length))
|
||||
if (argsMatch(info1, func->tokenDef->next(), (*tok)->next(), path, path_length))
|
||||
{
|
||||
func->hasBody = true;
|
||||
func->token = *tok;
|
||||
|
@ -709,7 +717,7 @@ void SymbolDatabase::addFunction(SpaceInfo **info, const Token **tok, const Toke
|
|||
}
|
||||
else if (func->tokenDef->str() == (*tok)->str() && (*tok)->previous()->str() != "~")
|
||||
{
|
||||
if (argsMatch(func->tokenDef->next(), (*tok)->next(), path, path_length))
|
||||
if (argsMatch(info1, func->tokenDef->next(), (*tok)->next(), path, path_length))
|
||||
{
|
||||
// normal function?
|
||||
if (!func->retFuncPtr && (*tok)->next()->link())
|
||||
|
@ -1866,7 +1874,7 @@ bool SymbolDatabase::isVirtualFunc(const SymbolDatabase::SpaceInfo *info, const
|
|||
}
|
||||
|
||||
// check for matching function parameters
|
||||
if (returnMatch && argsMatch(tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0))
|
||||
if (returnMatch && argsMatch(info, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ private:
|
|||
void addNewFunction(SpaceInfo **info, const Token **tok);
|
||||
|
||||
bool isFunction(const Token *tok, const Token **funcStart, const Token **argStart) const;
|
||||
bool argsMatch(const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
||||
bool argsMatch(const SpaceInfo *info, const Token *first, const Token *second, const std::string &path, unsigned int depth) const;
|
||||
|
||||
const SpaceInfo *findVarType(const SpaceInfo *start, const Token *type) const;
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ private:
|
|||
TEST_CASE(const39);
|
||||
TEST_CASE(const40); // ticket #2228
|
||||
TEST_CASE(const41); // ticket #2255
|
||||
TEST_CASE(const42); // ticket #2282
|
||||
TEST_CASE(constoperator1); // operator< can often be const
|
||||
TEST_CASE(constoperator2); // operator<<
|
||||
TEST_CASE(constoperator3);
|
||||
|
@ -4703,6 +4704,83 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void const42() // ticket #2282
|
||||
{
|
||||
checkConst("class Fred\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" struct AB { };\n"
|
||||
" bool f(AB * ab);\n"
|
||||
"};\n"
|
||||
"bool Fred::f(Fred::AB * ab)\n"
|
||||
"{\n"
|
||||
"}\n");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:5]: (style) The function 'Fred::f' can be const\n", errout.str());
|
||||
|
||||
checkConst("class Fred\n"
|
||||
"{\n"
|
||||
"public:\n"
|
||||
" struct AB {\n"
|
||||
" struct CD { };\n"
|
||||
" };\n"
|
||||
" bool f(AB::CD * cd);\n"
|
||||
"};\n"
|
||||
"bool Fred::f(Fred::AB::CD * cd)\n"
|
||||
"{\n"
|
||||
"}\n");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:7]: (style) The function 'Fred::f' can be const\n", errout.str());
|
||||
|
||||
checkConst("namespace NS {\n"
|
||||
" class Fred\n"
|
||||
" {\n"
|
||||
" public:\n"
|
||||
" struct AB {\n"
|
||||
" struct CD { };\n"
|
||||
" };\n"
|
||||
" bool f(AB::CD * cd);\n"
|
||||
" };\n"
|
||||
" bool Fred::f(Fred::AB::CD * cd)\n"
|
||||
" {\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:10] -> [test.cpp:8]: (style) The function 'NS::Fred::f' can be const\n", errout.str());
|
||||
|
||||
checkConst("namespace NS {\n"
|
||||
" class Fred\n"
|
||||
" {\n"
|
||||
" public:\n"
|
||||
" struct AB {\n"
|
||||
" struct CD { };\n"
|
||||
" };\n"
|
||||
" bool f(AB::CD * cd);\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
"bool NS::Fred::f(NS::Fred::AB::CD * cd)\n"
|
||||
"{\n"
|
||||
"}\n");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:8]: (style) The function 'NS::Fred::f' can be const\n", errout.str());
|
||||
|
||||
checkConst("class Foo {\n"
|
||||
" class Fred\n"
|
||||
" {\n"
|
||||
" public:\n"
|
||||
" struct AB {\n"
|
||||
" struct CD { };\n"
|
||||
" };\n"
|
||||
" bool f(AB::CD * cd);\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"bool Foo::Fred::f(Foo::Fred::AB::CD * cd)\n"
|
||||
"{\n"
|
||||
"}\n");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:11] -> [test.cpp:8]: (style) The function 'Foo::Fred::f' can be const\n", errout.str());
|
||||
}
|
||||
|
||||
// increment/decrement => not const
|
||||
void constincdec()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue