Support namespaces in CheckOther::checkIgnoredReturnValue()

This commit is contained in:
PKEuS 2015-08-15 12:19:14 +02:00
parent 4d80df2f4a
commit b77912a0b5
4 changed files with 33 additions and 7 deletions

View File

@ -2506,14 +2506,22 @@ void CheckOther::checkIgnoredReturnValue()
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (tok->varId() || !Token::Match(tok, "%name% (") || tok->strAt(-1) == "." || tok->next()->astOperand1() != tok)
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (tok->varId() || !Token::Match(tok, "%name% (") || tok->strAt(-1) == ".")
continue;
if (!tok->scope()->isExecutable())
if (!tok->scope()->isExecutable()) {
tok = tok->scope()->classEnd;
continue;
}
if (!tok->next()->astParent() && (!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) && _settings->library.useretval.find(tok->str()) != _settings->library.useretval.end())
const Token* parent = tok;
while (parent->astParent() && parent->astParent()->str() == "::")
parent = parent->astParent();
if (tok->next()->astOperand1() != parent)
continue;
if (!tok->next()->astParent() && (!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) && _settings->library.isUseRetVal(tok))
ignoredReturnValueError(tok, tok->str());
}
}

View File

@ -498,7 +498,7 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
} else if (functionnodename == "leak-ignore")
leakignore.insert(name);
else if (functionnodename == "use-retval")
useretval.insert(name);
_useretval.insert(name);
else if (functionnodename == "arg" && functionnode->Attribute("nr") != nullptr) {
const bool bAnyArg = strcmp(functionnode->Attribute("nr"),"any")==0;
const int nr = (bAnyArg) ? -1 : atoi(functionnode->Attribute("nr"));
@ -798,6 +798,11 @@ bool Library::isNotLibraryFunction(const Token *ftok) const
return args != callargs;
}
bool Library::isUseRetVal(const Token* ftok) const
{
return (_useretval.find(functionName(ftok)) != _useretval.end());
}
bool Library::isnoreturn(const Token *ftok) const
{
if (ftok->function() && ftok->function()->isAttributeNoreturn())

View File

@ -119,11 +119,13 @@ public:
std::set<std::string> leakignore;
std::set<std::string> functionconst;
std::set<std::string> functionpure;
std::set<std::string> useretval;
// returns true if ftok is not a library function
bool isNotLibraryFunction(const Token *ftok) const;
bool isUseRetVal(const Token* ftok) const;
bool isnoreturn(const Token *ftok) const;
bool isnotnoreturn(const Token *ftok) const;
@ -435,6 +437,7 @@ private:
};
int allocid;
std::set<std::string> _files;
std::set<std::string> _useretval;
std::map<std::string, int> _alloc; // allocation functions
std::map<std::string, int> _dealloc; // deallocation functions
std::map<std::string, bool> _noreturn; // is function noreturn?

View File

@ -6122,7 +6122,7 @@ private:
Settings settings;
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def>\n"
" <function name=\"mystrcmp\">\n"
" <function name=\"mystrcmp,foo::mystrcmp\">\n"
" <use-retval/>\n"
" <arg nr=\"1\"/>\n"
" <arg nr=\"2\"/>\n"
@ -6137,6 +6137,11 @@ private:
"}", "test.cpp", false, false, true, &settings);
ASSERT_EQUALS("[test.cpp:2]: (warning) Return value of function mystrcmp() is not used.\n", errout.str());
check("void foo() {\n"
" foo::mystrcmp(a, b);\n"
"}", "test.cpp", false, false, true, &settings);
ASSERT_EQUALS("[test.cpp:2]: (warning) Return value of function mystrcmp() is not used.\n", errout.str());
check("bool mystrcmp(char* a, char* b);\n" // cppcheck sees a custom strcmp definition, but it returns a value. Assume it is the one specified in the library.
"void foo() {\n"
" mystrcmp(a, b);\n"
@ -6159,6 +6164,11 @@ private:
"}", "test.cpp", false, false, true, &settings);
ASSERT_EQUALS("", errout.str());
check("void foo() {\n"
" return foo::mystrcmp(a, b);\n"
"}", "test.cpp", false, false, true, &settings);
ASSERT_EQUALS("", errout.str());
check("void foo() {\n"
" if(mystrcmp(a, b));\n"
"}", "test.cpp", false, false, true, &settings);